├── client ├── miniprogram │ ├── index.d.ts │ ├── pages │ │ ├── index │ │ │ ├── index.json │ │ │ ├── index.wxss │ │ │ ├── index.wxml │ │ │ ├── index.ts │ │ │ └── index.js │ │ └── logs │ │ │ ├── logs.json │ │ │ ├── logs.wxss │ │ │ ├── logs.wxml │ │ │ ├── logs.ts │ │ │ └── logs.js │ ├── sitemap.json │ ├── app.wxss │ ├── app.ts │ ├── app.json │ ├── service │ │ ├── todo.ts │ │ ├── sdk.ts │ │ └── proto_gen │ │ │ ├── todo │ │ │ ├── todo_pb.d.ts │ │ │ └── todo_pb.js │ │ │ └── auth │ │ │ ├── auth_pb.d.ts │ │ │ └── auth_pb.js │ ├── package.json │ ├── utils │ │ ├── util.ts │ │ └── util.js │ ├── tsconfig.json │ ├── project.config.json │ ├── app.js │ └── yarn.lock └── gen_ts.sh ├── banner.png ├── Interceptor.png ├── mingiprogram-v2.png ├── api-login.2fcc9f35.jpg ├── microsvcs ├── auth │ ├── api │ │ ├── auth.yaml │ │ ├── auth.proto │ │ └── gen │ │ │ └── v1 │ │ │ ├── auth_grpc.pb.go │ │ │ ├── auth.pb.gw.go │ │ │ └── auth.pb.go │ ├── wechat │ │ └── wechat.go │ ├── token │ │ ├── jwt.go │ │ └── jwt_test.go │ ├── auth │ │ └── auth.go │ ├── private.key │ └── main.go ├── todo │ ├── api │ │ ├── todo.yaml │ │ ├── todo.proto │ │ └── gen │ │ │ └── v1 │ │ │ ├── todo_grpc.pb.go │ │ │ ├── todo.pb.gw.go │ │ │ └── todo.pb.go │ ├── todo │ │ └── todo.go │ └── main.go ├── shared │ ├── mongo │ │ ├── mongo.go │ │ └── testing │ │ │ └── mongotesting.go │ ├── auth │ │ ├── public.key │ │ ├── token │ │ │ ├── token.go │ │ │ └── token_test.go │ │ └── auth.go │ └── server │ │ └── grpc.go ├── gen.sh ├── go.mod ├── dao │ ├── mongo.go │ └── mongo_test.go └── gateway │ └── main.go ├── .gitignore ├── README.md └── architecture_introduction_diagram.svg /client/miniprogram/index.d.ts: -------------------------------------------------------------------------------- 1 | interface IAppOption { 2 | globalData: {} 3 | } -------------------------------------------------------------------------------- /client/miniprogram/pages/index/index.json: -------------------------------------------------------------------------------- 1 | { 2 | "usingComponents": {} 3 | } -------------------------------------------------------------------------------- /banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hacker-Linner/go-grpc-gateway-v2-microservice/HEAD/banner.png -------------------------------------------------------------------------------- /Interceptor.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hacker-Linner/go-grpc-gateway-v2-microservice/HEAD/Interceptor.png -------------------------------------------------------------------------------- /client/miniprogram/pages/logs/logs.json: -------------------------------------------------------------------------------- 1 | { 2 | "navigationBarTitleText": "查看启动日志", 3 | "usingComponents": {} 4 | } -------------------------------------------------------------------------------- /mingiprogram-v2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hacker-Linner/go-grpc-gateway-v2-microservice/HEAD/mingiprogram-v2.png -------------------------------------------------------------------------------- /api-login.2fcc9f35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Hacker-Linner/go-grpc-gateway-v2-microservice/HEAD/api-login.2fcc9f35.jpg -------------------------------------------------------------------------------- /client/miniprogram/pages/logs/logs.wxss: -------------------------------------------------------------------------------- 1 | .log-list { 2 | display: flex; 3 | flex-direction: column; 4 | padding: 40rpx; 5 | } 6 | .log-item { 7 | margin: 10rpx; 8 | } 9 | -------------------------------------------------------------------------------- /microsvcs/auth/api/auth.yaml: -------------------------------------------------------------------------------- 1 | type: google.api.Service 2 | config_version: 3 3 | 4 | http: 5 | rules: 6 | - selector: auth.v1.AuthService.Login 7 | post: /v1/auth/login 8 | body: "*" -------------------------------------------------------------------------------- /microsvcs/todo/api/todo.yaml: -------------------------------------------------------------------------------- 1 | type: google.api.Service 2 | config_version: 3 3 | 4 | http: 5 | rules: 6 | - selector: todo.v1.TodoService.CreateTodo 7 | post: /v1/todo 8 | body: "*" -------------------------------------------------------------------------------- /client/miniprogram/sitemap.json: -------------------------------------------------------------------------------- 1 | { 2 | "desc": "关于本文件的更多信息,请参考文档 https://developers.weixin.qq.com/miniprogram/dev/framework/sitemap.html", 3 | "rules": [{ 4 | "action": "allow", 5 | "page": "*" 6 | }] 7 | } -------------------------------------------------------------------------------- /client/miniprogram/pages/logs/logs.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | {{index + 1}}. {{log}} 5 | 6 | 7 | -------------------------------------------------------------------------------- /client/miniprogram/app.wxss: -------------------------------------------------------------------------------- 1 | /**app.wxss**/ 2 | .container { 3 | height: 100%; 4 | display: flex; 5 | flex-direction: column; 6 | align-items: center; 7 | justify-content: space-between; 8 | padding: 200rpx 0; 9 | box-sizing: border-box; 10 | } 11 | -------------------------------------------------------------------------------- /client/miniprogram/app.ts: -------------------------------------------------------------------------------- 1 | import { SDK } from "./service/sdk" 2 | // app.ts 3 | App({ 4 | globalData: {}, 5 | onLaunch() { 6 | // 展示本地存储能力 7 | const logs = wx.getStorageSync('logs') || [] 8 | logs.unshift(Date.now()) 9 | wx.setStorageSync('logs', logs) 10 | // 登录 11 | SDK.login() 12 | }, 13 | }) -------------------------------------------------------------------------------- /microsvcs/todo/api/todo.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package todo.v1; 3 | option go_package="server/todo/api/gen/v1;todopb"; 4 | 5 | 6 | message CreateTodoRequest { 7 | string title = 1; 8 | } 9 | 10 | message CreateTodoResponse { 11 | } 12 | 13 | service TodoService { 14 | rpc CreateTodo (CreateTodoRequest) returns (CreateTodoResponse); 15 | } -------------------------------------------------------------------------------- /client/miniprogram/app.json: -------------------------------------------------------------------------------- 1 | { 2 | "pages": [ 3 | "pages/index/index", 4 | "pages/logs/logs" 5 | ], 6 | "window": { 7 | "backgroundTextStyle": "light", 8 | "navigationBarBackgroundColor": "#fff", 9 | "navigationBarTitleText": "Weixin", 10 | "navigationBarTextStyle": "black" 11 | }, 12 | "style": "v2", 13 | "sitemapLocation": "sitemap.json" 14 | } -------------------------------------------------------------------------------- /client/miniprogram/pages/index/index.wxss: -------------------------------------------------------------------------------- 1 | /**index.wxss**/ 2 | .userinfo { 3 | display: flex; 4 | flex-direction: column; 5 | align-items: center; 6 | color: #aaa; 7 | } 8 | 9 | .userinfo-avatar { 10 | overflow: hidden; 11 | width: 128rpx; 12 | height: 128rpx; 13 | margin: 20rpx; 14 | border-radius: 50%; 15 | } 16 | 17 | .usermotto { 18 | margin-top: 200px; 19 | } -------------------------------------------------------------------------------- /microsvcs/auth/api/auth.proto: -------------------------------------------------------------------------------- 1 | syntax = "proto3"; 2 | package auth.v1; 3 | option go_package="server/auth/api/gen/v1;authpb"; 4 | 5 | message LoginRequest { 6 | string code = 1; 7 | } 8 | 9 | message LoginResponse { 10 | string access_token = 1; 11 | int32 expires_in = 2; // 按 oauth2 约定走 12 | } 13 | 14 | service AuthService { 15 | rpc Login (LoginRequest) returns (LoginResponse); 16 | } -------------------------------------------------------------------------------- /client/miniprogram/pages/logs/logs.ts: -------------------------------------------------------------------------------- 1 | // logs.ts 2 | // const util = require('../../utils/util.js') 3 | import { formatTime } from '../../utils/util' 4 | 5 | Page({ 6 | data: { 7 | logs: [], 8 | }, 9 | onLoad() { 10 | this.setData({ 11 | logs: (wx.getStorageSync('logs') || []).map((log: string) => { 12 | return formatTime(new Date(log)) 13 | }), 14 | }) 15 | }, 16 | }) 17 | -------------------------------------------------------------------------------- /microsvcs/shared/mongo/mongo.go: -------------------------------------------------------------------------------- 1 | package mgo 2 | 3 | import ( 4 | "go.mongodb.org/mongo-driver/bson" 5 | "go.mongodb.org/mongo-driver/bson/primitive" 6 | ) 7 | 8 | const IDField = "_id" 9 | 10 | type ObjID struct { 11 | ID primitive.ObjectID `bson:"_id"` 12 | } 13 | 14 | func Set(v interface{}) bson.M { 15 | return bson.M{ 16 | "$set": v, 17 | } 18 | } 19 | 20 | func SetOnInsert(v interface{}) bson.M { 21 | return bson.M{ 22 | "$setOnInsert": v, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /client/miniprogram/service/todo.ts: -------------------------------------------------------------------------------- 1 | import { todo } from "./proto_gen/todo/todo_pb" 2 | import { SDK } from "./sdk" 3 | 4 | export namespace TodoService { 5 | export function CreateTodo(req: todo.v1.ICreateTodoRequest): Promise{ 6 | return SDK.sendRequestWithAuthRetry({ 7 | method: "POST", 8 | path: "/v1/todo", 9 | data: req, 10 | respMarshaller: todo.v1.CreateTodoResponse.fromObject 11 | }) 12 | } 13 | } -------------------------------------------------------------------------------- /microsvcs/gen.sh: -------------------------------------------------------------------------------- 1 | function gen { 2 | SVCS=$1 3 | PROTO_PATH=./${SVCS}/api 4 | GO_OUT_PATH=./${SVCS}/api/gen/v1 5 | mkdir -p ${GO_OUT_PATH} 6 | 7 | protoc -I=$PROTO_PATH --go_out=paths=source_relative:$GO_OUT_PATH ${SVCS}.proto 8 | protoc -I=$PROTO_PATH --go-grpc_out=paths=source_relative:$GO_OUT_PATH ${SVCS}.proto 9 | protoc -I=$PROTO_PATH --grpc-gateway_out=paths=source_relative,grpc_api_configuration=$PROTO_PATH/${SVCS}.yaml:$GO_OUT_PATH ${SVCS}.proto 10 | } 11 | gen auth 12 | gen todo -------------------------------------------------------------------------------- /microsvcs/shared/auth/public.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PUBLIC KEY----- 2 | MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnzyis1ZjfNB0bBgKFMSv 3 | vkTtwlvBsaJq7S5wA+kzeVOVpVWwkWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHc 4 | aT92whREFpLv9cj5lTeJSibyr/Mrm/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIy 5 | tvHWTxZYEcXLgAXFuUuaS3uF9gEiNQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0 6 | e+lf4s4OxQawWD79J9/5d3Ry0vbV3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWb 7 | V6L11BWkpzGXSW4Hv43qa+GSYOD2QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9 8 | MwIDAQAB 9 | -----END PUBLIC KEY----- -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | *.exe 3 | *.dll 4 | *.so 5 | *.dylib 6 | 7 | # Test binary, build with `go test -c` 8 | *.test 9 | 10 | # Output of the go coverage tool, specifically when used with LiteIDE 11 | *.out 12 | 13 | .DS_Store 14 | 15 | # Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736 16 | .glide/ 17 | .idea/ 18 | release/ 19 | build/ 20 | gcloud/ 21 | dist/ 22 | bin/ 23 | 24 | client/miniprogram/$node_modules 25 | client/miniprogram/node_modules 26 | client/miniprogram/miniprogram_npm -------------------------------------------------------------------------------- /client/miniprogram/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "miniprogram-ts-quickstart", 3 | "version": "1.0.0", 4 | "description": "", 5 | "scripts": { 6 | "compile": "./node_modules/typescript/bin/tsc", 7 | "tsc": "node ./node_modules/typescript/lib/tsc.js" 8 | }, 9 | "keywords": [], 10 | "author": "", 11 | "license": "", 12 | "dependencies": { 13 | "camelcase-keys": "^6.2.2", 14 | "protobufjs": "^6.10.2" 15 | }, 16 | "devDependencies": { 17 | "miniprogram-api-typings": "^3.3.0", 18 | "typescript": "^4.2.3" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /client/miniprogram/utils/util.ts: -------------------------------------------------------------------------------- 1 | export const formatTime = (date: Date) => { 2 | const year = date.getFullYear() 3 | const month = date.getMonth() + 1 4 | const day = date.getDate() 5 | const hour = date.getHours() 6 | const minute = date.getMinutes() 7 | const second = date.getSeconds() 8 | 9 | return ( 10 | [year, month, day].map(formatNumber).join('/') + 11 | ' ' + 12 | [hour, minute, second].map(formatNumber).join(':') 13 | ) 14 | } 15 | 16 | const formatNumber = (n: number) => { 17 | const s = n.toString() 18 | return s[1] ? s : '0' + s 19 | } 20 | -------------------------------------------------------------------------------- /client/gen_ts.sh: -------------------------------------------------------------------------------- 1 | function gen { 2 | SVCS=$1 3 | PROTO_PATH=../microsvcs/${SVCS}/api 4 | PBTS_BIN_DIR=./node_modules/.bin 5 | PBTS_OUT_DIR=./miniprogram/service/proto_gen/${SVCS} 6 | mkdir -p $PBTS_OUT_DIR 7 | 8 | $PBTS_BIN_DIR/pbjs -t static -w es6 $PROTO_PATH/${SVCS}.proto --no-create --no-encode --no-decode --no-verify --no-delimited -o $PBTS_OUT_DIR/${SVCS}_pb_tmp.js 9 | echo 'import * as $protobuf from "protobufjs";\n' > $PBTS_OUT_DIR/${SVCS}_pb.js 10 | cat $PBTS_OUT_DIR/${SVCS}_pb_tmp.js >> $PBTS_OUT_DIR/${SVCS}_pb.js 11 | rm $PBTS_OUT_DIR/${SVCS}_pb_tmp.js 12 | $PBTS_BIN_DIR/pbts -o $PBTS_OUT_DIR/${SVCS}_pb.d.ts $PBTS_OUT_DIR/${SVCS}_pb.js 13 | } 14 | gen auth 15 | gen todo -------------------------------------------------------------------------------- /microsvcs/auth/wechat/wechat.go: -------------------------------------------------------------------------------- 1 | package wechat 2 | 3 | import ( 4 | "fmt" 5 | 6 | weapp "github.com/medivhzhan/weapp/v2" 7 | ) 8 | 9 | // Service implements a wechat auth service 10 | type Service struct { 11 | AppID string 12 | AppSecret string 13 | } 14 | 15 | // Resolve resolves authorization code to wechat open id. 16 | func (s *Service) Resolve(code string) (string, error) { 17 | resp, err := weapp.Login(s.AppID, s.AppSecret, code) 18 | if err != nil { 19 | return "", fmt.Errorf("weapp.Login: %v", err) 20 | } 21 | 22 | if err = resp.GetResponseError(); err != nil { 23 | return "", fmt.Errorf("weapp response error: %v", err) 24 | } 25 | 26 | return resp.OpenID, nil 27 | } 28 | -------------------------------------------------------------------------------- /microsvcs/todo/todo/todo.go: -------------------------------------------------------------------------------- 1 | package todo 2 | 3 | import ( 4 | "context" 5 | "server/shared/auth" 6 | todopb "server/todo/api/gen/v1" 7 | 8 | "go.uber.org/zap" 9 | "google.golang.org/grpc/codes" 10 | "google.golang.org/grpc/status" 11 | ) 12 | 13 | type Service struct { 14 | Logger *zap.Logger 15 | todopb.UnimplementedTodoServiceServer 16 | } 17 | 18 | func (s *Service) CreateTodo(c context.Context, req *todopb.CreateTodoRequest) (*todopb.CreateTodoResponse, error) { 19 | // 确定是谁要创建这个 Todo? 20 | aid, err := auth.AcountIDFromContext(c) 21 | if err != nil { 22 | return nil, err 23 | } 24 | s.Logger.Info("create trip", zap.String("title", req.Title), zap.String("account_id", aid.String())) 25 | return nil, status.Error(codes.Unimplemented, "") 26 | } 27 | -------------------------------------------------------------------------------- /microsvcs/todo/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "log" 5 | "server/shared/server" 6 | todopb "server/todo/api/gen/v1" 7 | "server/todo/todo" 8 | 9 | "go.uber.org/zap" 10 | "google.golang.org/grpc" 11 | ) 12 | 13 | func main() { 14 | logger, err := zap.NewDevelopment() 15 | if err != nil { 16 | log.Fatalf("cannot create logger: %v", err) 17 | } 18 | 19 | logger.Sugar().Fatal( 20 | server.RunGRPCServer(&server.GRPCConfig{ 21 | Name: "todo", 22 | Addr: ":8082", 23 | AuthPublicKeyFile: "shared/auth/public.key", 24 | Logger: logger, 25 | RegisterFunc: func(s *grpc.Server) { 26 | todopb.RegisterTodoServiceServer(s, &todo.Service{ 27 | Logger: logger, 28 | }) 29 | }, 30 | }), 31 | ) 32 | } 33 | -------------------------------------------------------------------------------- /microsvcs/go.mod: -------------------------------------------------------------------------------- 1 | module server 2 | 3 | go 1.14 4 | 5 | require ( 6 | github.com/containerd/containerd v1.4.4 // indirect 7 | github.com/dgrijalva/jwt-go v3.2.0+incompatible 8 | github.com/docker/distribution v2.7.1+incompatible // indirect 9 | github.com/docker/docker v20.10.5+incompatible 10 | github.com/docker/go-connections v0.4.0 11 | github.com/docker/go-units v0.4.0 // indirect 12 | github.com/google/logger v1.1.0 13 | github.com/grpc-ecosystem/grpc-gateway/v2 v2.3.0 14 | github.com/medivhzhan/weapp/v2 v2.4.1 15 | github.com/opencontainers/go-digest v1.0.0 // indirect 16 | github.com/opencontainers/image-spec v1.0.1 // indirect 17 | go.mongodb.org/mongo-driver v1.5.1 18 | go.uber.org/zap v1.16.0 19 | google.golang.org/grpc v1.36.1 20 | google.golang.org/protobuf v1.26.0 21 | ) 22 | -------------------------------------------------------------------------------- /client/miniprogram/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "strictNullChecks": true, 4 | "noImplicitAny": true, 5 | "module": "CommonJS", 6 | "target": "ES5", 7 | "allowJs": false, 8 | "experimentalDecorators": true, 9 | "noImplicitThis": true, 10 | "noImplicitReturns": true, 11 | "alwaysStrict": true, 12 | "inlineSourceMap": true, 13 | "inlineSources": true, 14 | "noFallthroughCasesInSwitch": true, 15 | "noUnusedLocals": true, 16 | "noUnusedParameters": true, 17 | "strict": true, 18 | "removeComments": true, 19 | "pretty": true, 20 | "strictPropertyInitialization": true, 21 | "lib": ["es6"], 22 | "types": ["miniprogram-api-typings"] 23 | }, 24 | "include": [ 25 | "./**/*.ts" 26 | ], 27 | "exclude": [ 28 | "node_modules" 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /microsvcs/auth/token/jwt.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | import ( 4 | "crypto/rsa" 5 | "time" 6 | 7 | "github.com/dgrijalva/jwt-go" 8 | ) 9 | 10 | type JWTTokenGen struct { 11 | privateKey *rsa.PrivateKey 12 | issuer string 13 | nowFunc func() time.Time 14 | } 15 | 16 | func NewJWTTokenGen(issuer string, privateKey *rsa.PrivateKey) *JWTTokenGen { 17 | return &JWTTokenGen{ 18 | issuer: issuer, 19 | nowFunc: time.Now, 20 | privateKey: privateKey, 21 | } 22 | } 23 | 24 | func (t *JWTTokenGen) GenerateToken(accountID string, expire time.Duration) (string, error) { 25 | nowSec := t.nowFunc().Unix() 26 | token := jwt.NewWithClaims(jwt.SigningMethodRS512, jwt.StandardClaims{ 27 | Issuer: t.issuer, 28 | IssuedAt: nowSec, 29 | ExpiresAt: nowSec + int64(expire.Seconds()), 30 | Subject: accountID, 31 | }) 32 | return token.SignedString(t.privateKey) 33 | } 34 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Go + gRPC-Gateway(V2) 构建微服务实战系列 2 | 3 | 1. [云原生 API 网关,gRPC-Gateway V2 初探](https://mp.weixin.qq.com/s/9qDUDrYBgOWQ3s_jHxK4fQ) 4 | 2. [Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第一篇](https://mp.weixin.qq.com/s/OVyiFknEiN6e6WvZ6Dh9pg) 5 | 3. [Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务:第二篇](https://mp.weixin.qq.com/s/u5_bE58sMr4BNNMq1-H09Q) 6 | 4. [Go + gRPC-Gateway(V2) 构建微服务实战系列,小程序登录鉴权服务(三):RSA(RS512) 签名 JWT](https://mp.weixin.qq.com/s/Ksb0ql-wx7SqnfQMia9HLg) 7 | 5. [Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(四):自动生成 API TS 类型](https://mp.weixin.qq.com/s/8vY3KTggFH4PUHmX5P2_mw) 8 | 6. [Go+gRPC-Gateway(V2) 微服务实战,小程序登录鉴权服务(五):鉴权 gRPC-Interceptor 拦截器实战](https://mp.weixin.qq.com/s/o8qHdzd6kTct1s2HyL-bCw) 9 | 10 | ![](./architecture_introduction_diagram.svg) 11 | 12 | ![](./banner.png) 13 | 14 | ![](./api-login.2fcc9f35.jpg) 15 | 16 | ![](./Interceptor.png) 17 | 18 | ![](./mingiprogram-v2.png) 19 | -------------------------------------------------------------------------------- /microsvcs/shared/auth/token/token.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | import ( 4 | "crypto/rsa" 5 | "fmt" 6 | 7 | "github.com/dgrijalva/jwt-go" 8 | ) 9 | 10 | type JWTTokenVerifier struct { 11 | PublicKey *rsa.PublicKey 12 | } 13 | 14 | func (v *JWTTokenVerifier) Verify(token string) (string, error) { 15 | t, err := jwt.ParseWithClaims(token, &jwt.StandardClaims{}, func(t *jwt.Token) (interface{}, error) { 16 | return v.PublicKey, nil 17 | }) 18 | 19 | if err != nil { 20 | return "", fmt.Errorf("cannot parse token: %v", err) 21 | } 22 | 23 | if !t.Valid { 24 | return "", fmt.Errorf("token not valid") 25 | } 26 | 27 | clm, ok := t.Claims.(*jwt.StandardClaims) 28 | if !ok { 29 | return "", fmt.Errorf("token claim is not StandardClaims") 30 | } 31 | 32 | if err := clm.Valid(); err != nil { 33 | return "", fmt.Errorf("claim not valid: %v", err) 34 | } 35 | 36 | return clm.Subject, nil 37 | } 38 | -------------------------------------------------------------------------------- /client/miniprogram/pages/index/index.wxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 请使用1.4.4及以上版本基础库 14 | 15 | 16 | 17 | {{userInfo.nickName}} 18 | 19 | 20 | 21 | {{motto}} 22 | 23 | 24 | -------------------------------------------------------------------------------- /microsvcs/shared/server/grpc.go: -------------------------------------------------------------------------------- 1 | package server 2 | 3 | import ( 4 | "net" 5 | "server/shared/auth" 6 | 7 | "go.uber.org/zap" 8 | "google.golang.org/grpc" 9 | ) 10 | 11 | type GRPCConfig struct { 12 | Name string 13 | Addr string 14 | AuthPublicKeyFile string 15 | RegisterFunc func(*grpc.Server) 16 | Logger *zap.Logger 17 | } 18 | 19 | func RunGRPCServer(c *GRPCConfig) error { 20 | nameField := zap.String("name", c.Name) 21 | lis, err := net.Listen("tcp", c.Addr) 22 | if err != nil { 23 | c.Logger.Fatal("cannot listen", nameField, zap.Error(err)) 24 | } 25 | 26 | var opts []grpc.ServerOption 27 | if c.AuthPublicKeyFile != "" { 28 | in, err := auth.Interceptor(c.AuthPublicKeyFile) 29 | if err != nil { 30 | c.Logger.Fatal("cannot create auth interceptor", nameField, zap.Error(err)) 31 | } 32 | opts = append(opts, grpc.UnaryInterceptor(in)) 33 | } 34 | 35 | s := grpc.NewServer(opts...) 36 | c.RegisterFunc(s) 37 | 38 | c.Logger.Info("server started", nameField, zap.String("addr", c.Addr)) 39 | return s.Serve(lis) 40 | } 41 | -------------------------------------------------------------------------------- /microsvcs/dao/mongo.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | mgo "server/shared/mongo" 7 | 8 | "go.mongodb.org/mongo-driver/bson" 9 | "go.mongodb.org/mongo-driver/bson/primitive" 10 | "go.mongodb.org/mongo-driver/mongo" 11 | "go.mongodb.org/mongo-driver/mongo/options" 12 | ) 13 | 14 | const openIDField = "open_id" 15 | 16 | type Mongo struct { 17 | col *mongo.Collection 18 | newObjID func() primitive.ObjectID 19 | } 20 | 21 | func NewMongo(db *mongo.Database) *Mongo { 22 | return &Mongo{ 23 | col: db.Collection("account"), 24 | newObjID: primitive.NewObjectID, 25 | } 26 | } 27 | 28 | func (m *Mongo) ResolveAccountID(c context.Context, openID string) (string, error) { 29 | insertedID := m.newObjID() 30 | 31 | res := m.col.FindOneAndUpdate(c, bson.M{ 32 | openIDField: openID, 33 | }, mgo.SetOnInsert(bson.M{ 34 | mgo.IDField: insertedID, 35 | openIDField: openID, 36 | }), options.FindOneAndUpdate(). 37 | SetUpsert(true). 38 | SetReturnDocument(options.After)) 39 | 40 | if err := res.Err(); err != nil { 41 | return "", fmt.Errorf("cannot findOneAndUpdate: %v", err) 42 | } 43 | 44 | var row mgo.ObjID 45 | 46 | err := res.Decode(&row) 47 | if err != nil { 48 | return "", fmt.Errorf("cannot decode result: %v", err) 49 | } 50 | return row.ID.Hex(), nil 51 | } 52 | -------------------------------------------------------------------------------- /client/miniprogram/pages/index/index.ts: -------------------------------------------------------------------------------- 1 | // index.ts 2 | // 获取应用实例 3 | const app = getApp() 4 | 5 | Page({ 6 | data: { 7 | motto: '公众号:黑客下午茶', 8 | userInfo: {}, 9 | hasUserInfo: false, 10 | canIUse: wx.canIUse('button.open-type.getUserInfo'), 11 | canIUseGetUserProfile: false, 12 | canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') // 如需尝试获取用户信息可改为false 13 | }, 14 | // 事件处理函数 15 | bindViewTap() { 16 | wx.navigateTo({ 17 | url: '../logs/logs', 18 | }) 19 | }, 20 | onLoad() { 21 | // @ts-ignore 22 | if (wx.getUserProfile) { 23 | this.setData({ 24 | canIUseGetUserProfile: true 25 | }) 26 | } 27 | }, 28 | getUserProfile() { 29 | // 推荐使用wx.getUserProfile获取用户信息,开发者每次通过该接口获取用户个人信息均需用户确认,开发者妥善保管用户快速填写的头像昵称,避免重复弹窗 30 | wx.getUserProfile({ 31 | desc: '展示用户信息', // 声明获取用户个人信息后的用途,后续会展示在弹窗中,请谨慎填写 32 | success: (res) => { 33 | console.log(res) 34 | this.setData({ 35 | userInfo: res.userInfo, 36 | hasUserInfo: true 37 | }) 38 | } 39 | }) 40 | }, 41 | getUserInfo(e: any) { 42 | // 不推荐使用getUserInfo获取用户信息,预计自2021年4月13日起,getUserInfo将不再弹出弹窗,并直接返回匿名的用户个人信息 43 | console.log(e) 44 | this.setData({ 45 | userInfo: e.detail.userInfo, 46 | hasUserInfo: true 47 | }) 48 | } 49 | }) 50 | -------------------------------------------------------------------------------- /client/miniprogram/pages/logs/logs.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var util_1 = require("../../utils/util"); 4 | Page({ 5 | data: { 6 | logs: [], 7 | }, 8 | onLoad: function () { 9 | this.setData({ 10 | logs: (wx.getStorageSync('logs') || []).map(function (log) { 11 | return util_1.formatTime(new Date(log)); 12 | }), 13 | }); 14 | }, 15 | }); 16 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibG9ncy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxvZ3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFFQSx5Q0FBNkM7QUFFN0MsSUFBSSxDQUFDO0lBQ0gsSUFBSSxFQUFFO1FBQ0osSUFBSSxFQUFFLEVBQUU7S0FDVDtJQUNELE1BQU0sRUFBTjtRQUNFLElBQUksQ0FBQyxPQUFPLENBQUM7WUFDWCxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFDLEdBQVc7Z0JBQ3RELE9BQU8saUJBQVUsQ0FBQyxJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFBO1lBQ2xDLENBQUMsQ0FBQztTQUNILENBQUMsQ0FBQTtJQUNKLENBQUM7Q0FDRixDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBsb2dzLnRzXG4vLyBjb25zdCB1dGlsID0gcmVxdWlyZSgnLi4vLi4vdXRpbHMvdXRpbC5qcycpXG5pbXBvcnQgeyBmb3JtYXRUaW1lIH0gZnJvbSAnLi4vLi4vdXRpbHMvdXRpbCdcblxuUGFnZSh7XG4gIGRhdGE6IHtcbiAgICBsb2dzOiBbXSxcbiAgfSxcbiAgb25Mb2FkKCkge1xuICAgIHRoaXMuc2V0RGF0YSh7XG4gICAgICBsb2dzOiAod3guZ2V0U3RvcmFnZVN5bmMoJ2xvZ3MnKSB8fCBbXSkubWFwKChsb2c6IHN0cmluZykgPT4ge1xuICAgICAgICByZXR1cm4gZm9ybWF0VGltZShuZXcgRGF0ZShsb2cpKVxuICAgICAgfSksXG4gICAgfSlcbiAgfSxcbn0pXG4iXX0= -------------------------------------------------------------------------------- /microsvcs/auth/token/jwt_test.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "testing" 7 | "time" 8 | 9 | "github.com/dgrijalva/jwt-go" 10 | "github.com/google/logger" 11 | "go.uber.org/zap" 12 | ) 13 | 14 | func TestGenerateToken(t *testing.T) { 15 | pkFile, err := os.Open("../private.key") 16 | if err != nil { 17 | logger.Fatal("cannot open private key", zap.Error(err)) 18 | } 19 | pkBytes, err := ioutil.ReadAll(pkFile) 20 | if err != nil { 21 | logger.Fatal("cannot read private key", zap.Error(err)) 22 | } 23 | key, err := jwt.ParseRSAPrivateKeyFromPEM(pkBytes) 24 | if err != nil { 25 | logger.Fatal("cannot parse private key", zap.Error(err)) 26 | } 27 | g := NewJWTTokenGen("server/auth", key) 28 | g.nowFunc = func() time.Time { 29 | return time.Unix(1516239022, 0) 30 | } 31 | tkn, err := g.GenerateToken("607266aa512e006d58b79d22", 2*time.Hour) 32 | if err != nil { 33 | t.Errorf("cannot generate token: %v", err) 34 | } 35 | 36 | want := "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTYyNDYyMjIsImlhdCI6MTUxNjIzOTAyMiwiaXNzIjoic2VydmVyL2F1dGgiLCJzdWIiOiI2MDcyNjZhYTUxMmUwMDZkNThiNzlkMjIifQ.nwhaGZ0dozftexVfr9KM9ZVAzsPudhLs-n-yyrrjkbFTYA69rsEd35M0vc1gJ1DNMJk_v-1yUhkgRpxzP2Jiy1Lw8fqIlAk8l9EpDE77oJ9Dal6Rl26GERYZOkCvbq02fKSVj4drlSr75fIce9EnQq2xIVyvvNNty-QvHXTX29QQv-6c8vVYIrCFxtooARN9p8OSpg0hzc-YzsXo64lbUvbLIws27TJNwhctbqrOYQuX9XU3UhJ4Ik0Yt2cLc4LjuqI52Grvf89mJMmM5jnHQv0tKI2guvxNwlC3WN50dCIcuo1zjO-_eSje5OvqP7FKR1eSwnEcZiZQ8qwDDGi8pA" 37 | 38 | if tkn != want { 39 | t.Errorf("wrong token generated. want: %q, got: %q", want, tkn) 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /client/miniprogram/project.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "description": "项目配置文件", 3 | "packOptions": { 4 | "ignore": [] 5 | }, 6 | "compileType": "miniprogram", 7 | "libVersion": "2.16.0", 8 | "projectname": "go-grpc-gateway-v2-microservice", 9 | "scripts": { 10 | "beforeCompile": "npm run tsc", 11 | "beforePreview": "npm run tsc", 12 | "beforeUpload": "npm run tsc" 13 | }, 14 | "setting": { 15 | "urlCheck": false, 16 | "es6": true, 17 | "enhance": true, 18 | "postcss": true, 19 | "preloadBackgroundData": false, 20 | "minified": true, 21 | "newFeature": false, 22 | "coverView": true, 23 | "nodeModules": true, 24 | "autoAudits": false, 25 | "showShadowRootInWxmlPanel": true, 26 | "scopeDataCheck": false, 27 | "uglifyFileName": false, 28 | "checkInvalidKey": true, 29 | "checkSiteMap": true, 30 | "uploadWithSourceMap": true, 31 | "compileHotReLoad": false, 32 | "useMultiFrameRuntime": true, 33 | "useApiHook": true, 34 | "useApiHostProcess": false, 35 | "babelSetting": { 36 | "ignore": [], 37 | "disablePlugins": [], 38 | "outputPath": "" 39 | }, 40 | "enableEngineNative": false, 41 | "bundle": false, 42 | "useIsolateContext": true, 43 | "useCompilerModule": true, 44 | "userConfirmedUseCompilerModuleSwitch": false, 45 | "userConfirmedBundleSwitch": false, 46 | "packNpmManually": false, 47 | "packNpmRelationList": [], 48 | "minifyWXSS": true 49 | }, 50 | "simulatorType": "wechat", 51 | "simulatorPluginLibVersion": {}, 52 | "appid": "wx63842eaabb7233b6", 53 | "condition": {} 54 | } -------------------------------------------------------------------------------- /microsvcs/auth/auth/auth.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "context" 5 | authpb "server/auth/api/gen/v1" 6 | "server/dao" 7 | "time" 8 | 9 | "go.uber.org/zap" 10 | "google.golang.org/grpc/codes" 11 | "google.golang.org/grpc/status" 12 | ) 13 | 14 | type Service struct { 15 | Mongo *dao.Mongo 16 | Logger *zap.Logger 17 | OpenIDResolver OpenIDResolver 18 | TokenGenerator TokenGenerator 19 | TokenExpire time.Duration 20 | authpb.UnimplementedAuthServiceServer 21 | } 22 | 23 | type OpenIDResolver interface { 24 | Resolve(code string) (string, error) 25 | } 26 | 27 | type TokenGenerator interface { 28 | GenerateToken(accountID string, expire time.Duration) (string, error) 29 | } 30 | 31 | func (s *Service) Login(c context.Context, req *authpb.LoginRequest) (*authpb.LoginResponse, error) { 32 | s.Logger.Info("received code", 33 | zap.String("code", req.Code)) 34 | 35 | openID, err := s.OpenIDResolver.Resolve(req.Code) 36 | if err != nil { 37 | return nil, status.Errorf(codes.Unavailable, 38 | "cannot resolve openid: %v", err) 39 | } 40 | 41 | accountID, err := s.Mongo.ResolveAccountID(c, openID) 42 | if err != nil { 43 | s.Logger.Error("cannot resolve account id", zap.Error(err)) 44 | return nil, status.Error(codes.Internal, "") 45 | } 46 | 47 | tkn, err := s.TokenGenerator.GenerateToken(accountID, s.TokenExpire) 48 | if err != nil { 49 | s.Logger.Error("cannot generate token", zap.Error(err)) 50 | return nil, status.Error(codes.Internal, "") 51 | } 52 | 53 | return &authpb.LoginResponse{ 54 | AccessToken: tkn, 55 | ExpiresIn: int32(s.TokenExpire.Seconds()), 56 | }, nil 57 | } 58 | -------------------------------------------------------------------------------- /microsvcs/shared/mongo/testing/mongotesting.go: -------------------------------------------------------------------------------- 1 | package mongotesting 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/docker/docker/api/types" 9 | "github.com/docker/docker/api/types/container" 10 | "github.com/docker/docker/client" 11 | "github.com/docker/go-connections/nat" 12 | ) 13 | 14 | const ( 15 | image = "mongo:4.4.5" 16 | containerPort = "27017/tcp" 17 | ) 18 | 19 | func RunWithMongoInDocker(m *testing.M, mongoURI *string) int { 20 | c, err := client.NewClientWithOpts() 21 | if err != nil { 22 | panic(err) 23 | } 24 | 25 | ctx := context.Background() 26 | 27 | resp, err := c.ContainerCreate(ctx, &container.Config{ 28 | Image: image, 29 | ExposedPorts: nat.PortSet{ 30 | containerPort: {}, 31 | }, 32 | }, &container.HostConfig{ 33 | PortBindings: nat.PortMap{ 34 | containerPort: []nat.PortBinding{ 35 | { 36 | HostIP: "127.0.0.1", 37 | HostPort: "0", // 随机挑一个端口 38 | }, 39 | }, 40 | }, 41 | }, nil, nil, "") 42 | if err != nil { 43 | panic(err) 44 | } 45 | containerID := resp.ID 46 | defer func() { 47 | err := c.ContainerRemove(ctx, containerID, types.ContainerRemoveOptions{Force: true}) 48 | if err != nil { 49 | panic(err) 50 | } 51 | }() 52 | 53 | err = c.ContainerStart(ctx, containerID, types.ContainerStartOptions{}) 54 | if err != nil { 55 | panic(err) 56 | } 57 | inspRes, err := c.ContainerInspect(ctx, containerID) 58 | if err != nil { 59 | panic(err) 60 | } 61 | hostPort := inspRes.NetworkSettings.Ports[containerPort][0] 62 | *mongoURI = fmt.Sprintf("mongodb://%s:%s", hostPort.HostIP, hostPort.HostPort) 63 | 64 | return m.Run() 65 | } 66 | -------------------------------------------------------------------------------- /microsvcs/auth/private.key: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEogIBAAKCAQEAnzyis1ZjfNB0bBgKFMSvvkTtwlvBsaJq7S5wA+kzeVOVpVWw 3 | kWdVha4s38XM/pa/yr47av7+z3VTmvDRyAHcaT92whREFpLv9cj5lTeJSibyr/Mr 4 | m/YtjCZVWgaOYIhwrXwKLqPr/11inWsAkfIytvHWTxZYEcXLgAXFuUuaS3uF9gEi 5 | NQwzGTU1v0FqkqTBr4B8nW3HCN47XUu0t8Y0e+lf4s4OxQawWD79J9/5d3Ry0vbV 6 | 3Am1FtGJiJvOwRsIfVChDpYStTcHTCMqtvWbV6L11BWkpzGXSW4Hv43qa+GSYOD2 7 | QU68Mb59oSk2OB+BtOLpJofmbGEGgvmwyCI9MwIDAQABAoIBACiARq2wkltjtcjs 8 | kFvZ7w1JAORHbEufEO1Eu27zOIlqbgyAcAl7q+/1bip4Z/x1IVES84/yTaM8p0go 9 | amMhvgry/mS8vNi1BN2SAZEnb/7xSxbflb70bX9RHLJqKnp5GZe2jexw+wyXlwaM 10 | +bclUCrh9e1ltH7IvUrRrQnFJfh+is1fRon9Co9Li0GwoN0x0byrrngU8Ak3Y6D9 11 | D8GjQA4Elm94ST3izJv8iCOLSDBmzsPsXfcCUZfmTfZ5DbUDMbMxRnSo3nQeoKGC 12 | 0Lj9FkWcfmLcpGlSXTO+Ww1L7EGq+PT3NtRae1FZPwjddQ1/4V905kyQFLamAA5Y 13 | lSpE2wkCgYEAy1OPLQcZt4NQnQzPz2SBJqQN2P5u3vXl+zNVKP8w4eBv0vWuJJF+ 14 | hkGNnSxXQrTkvDOIUddSKOzHHgSg4nY6K02ecyT0PPm/UZvtRpWrnBjcEVtHEJNp 15 | bU9pLD5iZ0J9sbzPU/LxPmuAP2Bs8JmTn6aFRspFrP7W0s1Nmk2jsm0CgYEAyH0X 16 | +jpoqxj4efZfkUrg5GbSEhf+dZglf0tTOA5bVg8IYwtmNk/pniLG/zI7c+GlTc9B 17 | BwfMr59EzBq/eFMI7+LgXaVUsM/sS4Ry+yeK6SJx/otIMWtDfqxsLD8CPMCRvecC 18 | 2Pip4uSgrl0MOebl9XKp57GoaUWRWRHqwV4Y6h8CgYAZhI4mh4qZtnhKjY4TKDjx 19 | QYufXSdLAi9v3FxmvchDwOgn4L+PRVdMwDNms2bsL0m5uPn104EzM6w1vzz1zwKz 20 | 5pTpPI0OjgWN13Tq8+PKvm/4Ga2MjgOgPWQkslulO/oMcXbPwWC3hcRdr9tcQtn9 21 | Imf9n2spL/6EDFId+Hp/7QKBgAqlWdiXsWckdE1Fn91/NGHsc8syKvjjk1onDcw0 22 | NvVi5vcba9oGdElJX3e9mxqUKMrw7msJJv1MX8LWyMQC5L6YNYHDfbPF1q5L4i8j 23 | 8mRex97UVokJQRRA452V2vCO6S5ETgpnad36de3MUxHgCOX3qL382Qx9/THVmbma 24 | 3YfRAoGAUxL/Eu5yvMK8SAt/dJK6FedngcM3JEFNplmtLYVLWhkIlNRGDwkg3I5K 25 | y18Ae9n7dHVueyslrb6weq7dTkYDi3iOYRW8HRkIQh06wEdbxt0shTzAJvvCQfrB 26 | jg/3747WSsf/zBTcHihTRBdAv6OmdhV4/dD5YBfLAkLrd+mX7iE= 27 | -----END RSA PRIVATE KEY----- -------------------------------------------------------------------------------- /microsvcs/gateway/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "log" 6 | "net/http" 7 | 8 | authpb "server/auth/api/gen/v1" 9 | todopb "server/todo/api/gen/v1" 10 | 11 | "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" 12 | "go.uber.org/zap" 13 | "google.golang.org/grpc" 14 | "google.golang.org/protobuf/encoding/protojson" 15 | ) 16 | 17 | func main() { 18 | // logger 19 | logger, err := zap.NewDevelopment() 20 | if err != nil { 21 | log.Fatalf("cannot create logger: %v", err) 22 | } 23 | 24 | c := context.Background() 25 | c, cancel := context.WithCancel(c) 26 | defer cancel() 27 | 28 | mux := runtime.NewServeMux(runtime.WithMarshalerOption( 29 | runtime.MIMEWildcard, 30 | &runtime.JSONPb{ 31 | MarshalOptions: protojson.MarshalOptions{ 32 | UseEnumNumbers: true, 33 | UseProtoNames: true, 34 | }, 35 | UnmarshalOptions: protojson.UnmarshalOptions{ 36 | DiscardUnknown: true, // If DiscardUnknown is set, unknown fields are ignored. 37 | }, 38 | }, 39 | )) 40 | 41 | serverConfig := []struct { 42 | name string 43 | addr string 44 | registerFunc func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) 45 | }{ 46 | { 47 | name: "auth", 48 | addr: "localhost:8081", 49 | registerFunc: authpb.RegisterAuthServiceHandlerFromEndpoint, 50 | }, 51 | { 52 | name: "todo", 53 | addr: "localhost:8082", 54 | registerFunc: todopb.RegisterTodoServiceHandlerFromEndpoint, 55 | }, 56 | } 57 | 58 | for _, s := range serverConfig { 59 | err := s.registerFunc( 60 | c, mux, s.addr, 61 | []grpc.DialOption{grpc.WithInsecure()}, 62 | ) 63 | if err != nil { 64 | logger.Sugar().Fatalf("cannot register service %s : %v", s.name, err) 65 | } 66 | } 67 | addr := ":8080" 68 | logger.Sugar().Infof("grpc gateway started at %s", addr) 69 | logger.Sugar().Fatal(http.ListenAndServe(addr, mux)) 70 | } 71 | -------------------------------------------------------------------------------- /microsvcs/auth/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "context" 5 | "io/ioutil" 6 | "log" 7 | "os" 8 | authpb "server/auth/api/gen/v1" 9 | "server/auth/auth" 10 | "server/auth/token" 11 | "server/auth/wechat" 12 | "server/dao" 13 | "server/shared/server" 14 | "time" 15 | 16 | "github.com/dgrijalva/jwt-go" 17 | "go.mongodb.org/mongo-driver/mongo" 18 | "go.mongodb.org/mongo-driver/mongo/options" 19 | "go.uber.org/zap" 20 | "google.golang.org/grpc" 21 | ) 22 | 23 | func main() { 24 | // logger 25 | logger, err := zap.NewDevelopment() 26 | if err != nil { 27 | log.Fatalf("cannot create logger: %v", err) 28 | } 29 | 30 | // mongo 31 | c := context.Background() 32 | mongoClient, err := mongo.Connect(c, options.Client().ApplyURI("mongodb://localhost:27017/?readPreference=primary&appname=mongodb-vscode%200.5.0&ssl=false")) 33 | if err != nil { 34 | logger.Fatal("cannot connect mongodb", zap.Error(err)) 35 | } 36 | 37 | // private.key 38 | pkFile, err := os.Open("auth/private.key") 39 | if err != nil { 40 | logger.Fatal("cannot open private key", zap.Error(err)) 41 | } 42 | 43 | pkBytes, err := ioutil.ReadAll(pkFile) 44 | if err != nil { 45 | logger.Fatal("cannot read private key", zap.Error(err)) 46 | } 47 | 48 | privKey, err := jwt.ParseRSAPrivateKeyFromPEM(pkBytes) 49 | if err != nil { 50 | logger.Fatal("cannot parse private key", zap.Error(err)) 51 | } 52 | 53 | // RunGRPCServer 54 | logger.Sugar().Fatal( 55 | server.RunGRPCServer(&server.GRPCConfig{ 56 | Name: "auth", 57 | Addr: ":8081", 58 | Logger: logger, 59 | RegisterFunc: func(s *grpc.Server) { 60 | authpb.RegisterAuthServiceServer(s, &auth.Service{ 61 | OpenIDResolver: &wechat.Service{ 62 | AppID: "your-appid", 63 | AppSecret: "your-appsecret", 64 | }, 65 | Mongo: dao.NewMongo(mongoClient.Database("grpc-gateway-auth")), 66 | Logger: logger, 67 | TokenExpire: 2 * time.Hour, 68 | TokenGenerator: token.NewJWTTokenGen("server/auth", privKey), 69 | }) 70 | }, 71 | }), 72 | ) 73 | } 74 | -------------------------------------------------------------------------------- /microsvcs/dao/mongo_test.go: -------------------------------------------------------------------------------- 1 | package dao 2 | 3 | import ( 4 | "context" 5 | "os" 6 | mgo "server/shared/mongo" 7 | mongotesting "server/shared/mongo/testing" 8 | "testing" 9 | 10 | "go.mongodb.org/mongo-driver/bson" 11 | "go.mongodb.org/mongo-driver/bson/primitive" 12 | "go.mongodb.org/mongo-driver/mongo" 13 | "go.mongodb.org/mongo-driver/mongo/options" 14 | ) 15 | 16 | var mongoURI string 17 | 18 | func TestResolveAccountID(t *testing.T) { 19 | c := context.Background() 20 | mc, err := mongo.Connect(c, options.Client().ApplyURI(mongoURI)) 21 | if err != nil { 22 | t.Fatalf("cannot connect mongodb: %v", err) 23 | } 24 | m := NewMongo(mc.Database("grpc-gateway-auth")) 25 | _, err = m.col.InsertMany(c, []interface{}{ 26 | bson.M{ 27 | mgo.IDField: mustObjID("606f12ff0ba74007267bfeee"), 28 | openIDField: "openid_1", 29 | }, 30 | bson.M{ 31 | mgo.IDField: mustObjID("606f12ff0ba74007267bfeef"), 32 | openIDField: "openid_2", 33 | }, 34 | }) 35 | 36 | if err != nil { 37 | t.Fatalf("cannot insert initial values: %v", err) 38 | } 39 | 40 | m.newObjID = func() primitive.ObjectID { 41 | return mustObjID("606f12ff0ba74007267bfef0") 42 | } 43 | 44 | cases := []struct { 45 | name string 46 | openID string 47 | want string 48 | }{ 49 | { 50 | name: "existing_user", 51 | openID: "openid_1", 52 | want: "606f12ff0ba74007267bfeee", 53 | }, 54 | { 55 | name: "another_existing_user", 56 | openID: "openid_2", 57 | want: "606f12ff0ba74007267bfeef", 58 | }, 59 | { 60 | name: "new_user", 61 | openID: "openid_3", 62 | want: "606f12ff0ba74007267bfef0", 63 | }, 64 | } 65 | 66 | for _, cc := range cases { 67 | t.Run(cc.name, func(t *testing.T) { 68 | id, err := m.ResolveAccountID(context.Background(), cc.openID) 69 | if err != nil { 70 | t.Errorf("failed resolve account id for %q: %v", cc.openID, err) 71 | } 72 | if id != cc.want { 73 | t.Errorf("resolve account id: want: %q; got: %q", cc.want, id) 74 | } 75 | }) 76 | } 77 | } 78 | 79 | func mustObjID(hex string) primitive.ObjectID { 80 | objID, err := primitive.ObjectIDFromHex(hex) 81 | if err != nil { 82 | panic(err) 83 | } 84 | return objID 85 | } 86 | 87 | func TestMain(m *testing.M) { 88 | os.Exit(mongotesting.RunWithMongoInDocker(m, &mongoURI)) 89 | } 90 | -------------------------------------------------------------------------------- /client/miniprogram/utils/util.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | exports.formatTime = void 0; 4 | var formatTime = function (date) { 5 | var year = date.getFullYear(); 6 | var month = date.getMonth() + 1; 7 | var day = date.getDate(); 8 | var hour = date.getHours(); 9 | var minute = date.getMinutes(); 10 | var second = date.getSeconds(); 11 | return ([year, month, day].map(formatNumber).join('/') + 12 | ' ' + 13 | [hour, minute, second].map(formatNumber).join(':')); 14 | }; 15 | exports.formatTime = formatTime; 16 | var formatNumber = function (n) { 17 | var s = n.toString(); 18 | return s[1] ? s : '0' + s; 19 | }; 20 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInV0aWwudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQU8sSUFBTSxVQUFVLEdBQUcsVUFBQyxJQUFVO0lBQ25DLElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUMvQixJQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFBO0lBQ2pDLElBQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQTtJQUMxQixJQUFNLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUE7SUFDNUIsSUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFBO0lBQ2hDLElBQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQTtJQUVoQyxPQUFPLENBQ0wsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQzlDLEdBQUc7UUFDSCxDQUFDLElBQUksRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLFlBQVksQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FDbkQsQ0FBQTtBQUNILENBQUMsQ0FBQTtBQWJZLFFBQUEsVUFBVSxjQWF0QjtBQUVELElBQU0sWUFBWSxHQUFHLFVBQUMsQ0FBUztJQUM3QixJQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsUUFBUSxFQUFFLENBQUE7SUFDdEIsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQTtBQUMzQixDQUFDLENBQUEiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgY29uc3QgZm9ybWF0VGltZSA9IChkYXRlOiBEYXRlKSA9PiB7XG4gIGNvbnN0IHllYXIgPSBkYXRlLmdldEZ1bGxZZWFyKClcbiAgY29uc3QgbW9udGggPSBkYXRlLmdldE1vbnRoKCkgKyAxXG4gIGNvbnN0IGRheSA9IGRhdGUuZ2V0RGF0ZSgpXG4gIGNvbnN0IGhvdXIgPSBkYXRlLmdldEhvdXJzKClcbiAgY29uc3QgbWludXRlID0gZGF0ZS5nZXRNaW51dGVzKClcbiAgY29uc3Qgc2Vjb25kID0gZGF0ZS5nZXRTZWNvbmRzKClcblxuICByZXR1cm4gKFxuICAgIFt5ZWFyLCBtb250aCwgZGF5XS5tYXAoZm9ybWF0TnVtYmVyKS5qb2luKCcvJykgK1xuICAgICcgJyArXG4gICAgW2hvdXIsIG1pbnV0ZSwgc2Vjb25kXS5tYXAoZm9ybWF0TnVtYmVyKS5qb2luKCc6JylcbiAgKVxufVxuXG5jb25zdCBmb3JtYXROdW1iZXIgPSAobjogbnVtYmVyKSA9PiB7XG4gIGNvbnN0IHMgPSBuLnRvU3RyaW5nKClcbiAgcmV0dXJuIHNbMV0gPyBzIDogJzAnICsgc1xufVxuIl19 -------------------------------------------------------------------------------- /microsvcs/shared/auth/auth.go: -------------------------------------------------------------------------------- 1 | package auth 2 | 3 | import ( 4 | "context" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | "strings" 9 | 10 | "github.com/dgrijalva/jwt-go" 11 | "google.golang.org/grpc" 12 | "google.golang.org/grpc/codes" 13 | "google.golang.org/grpc/metadata" 14 | "google.golang.org/grpc/status" 15 | 16 | "server/shared/auth/token" 17 | ) 18 | 19 | const ( 20 | authorizationHeader = "authorization" 21 | bearerPrefix = "Bearer " 22 | ) 23 | 24 | func Interceptor(publicKeyFile string) (grpc.UnaryServerInterceptor, error) { 25 | f, err := os.Open(publicKeyFile) 26 | if err != nil { 27 | return nil, fmt.Errorf("cannot open public key file: %v", err) 28 | } 29 | 30 | b, err := ioutil.ReadAll(f) 31 | if err != nil { 32 | return nil, fmt.Errorf("cannot read public key: %v", err) 33 | } 34 | 35 | pubKey, err := jwt.ParseRSAPublicKeyFromPEM(b) 36 | if err != nil { 37 | return nil, fmt.Errorf("cannot parse public key: %v", err) 38 | } 39 | 40 | i := &interceptor{ 41 | verifier: &token.JWTTokenVerifier{PublicKey: pubKey}, 42 | } 43 | 44 | return i.HandleReq, nil 45 | 46 | } 47 | 48 | type tokenVerifier interface { 49 | Verify(token string) (string, error) 50 | } 51 | 52 | type interceptor struct { 53 | verifier tokenVerifier 54 | } 55 | 56 | func (i *interceptor) HandleReq(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (resp interface{}, err error) { 57 | tkn, err := tokenFromContext(ctx) 58 | if err != nil { 59 | return nil, status.Error(codes.Unauthenticated, "") 60 | } 61 | 62 | aid, err := i.verifier.Verify(tkn) 63 | if err != nil { 64 | return nil, status.Errorf(codes.Unauthenticated, "token not valid: %v", err) 65 | } 66 | return handler(ContextWithAccountID(ctx, AccountID(aid)), req) 67 | } 68 | 69 | func tokenFromContext(c context.Context) (string, error) { 70 | unauthenticated := status.Error(codes.Unauthenticated, "") 71 | m, ok := metadata.FromIncomingContext(c) 72 | if !ok { 73 | return "", unauthenticated 74 | } 75 | 76 | tkn := "" 77 | for _, v := range m[authorizationHeader] { 78 | if strings.HasPrefix(v, bearerPrefix) { 79 | tkn = v[len(bearerPrefix):] 80 | } 81 | } 82 | 83 | if tkn == "" { 84 | return "", unauthenticated 85 | } 86 | 87 | return tkn, nil 88 | } 89 | 90 | type accountIDKey struct{} 91 | 92 | type AccountID string 93 | 94 | func (a AccountID) String() string { 95 | return string(a) 96 | } 97 | 98 | func ContextWithAccountID(c context.Context, aid AccountID) context.Context { 99 | return context.WithValue(c, accountIDKey{}, aid) 100 | } 101 | 102 | func AcountIDFromContext(c context.Context) (AccountID, error) { 103 | v := c.Value(accountIDKey{}) 104 | aid, ok := v.(AccountID) 105 | if !ok { 106 | return "", status.Error(codes.Unauthenticated, "") 107 | } 108 | return aid, nil 109 | } 110 | -------------------------------------------------------------------------------- /microsvcs/shared/auth/token/token_test.go: -------------------------------------------------------------------------------- 1 | package token 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "testing" 7 | "time" 8 | 9 | "github.com/dgrijalva/jwt-go" 10 | "github.com/google/logger" 11 | "go.uber.org/zap" 12 | ) 13 | 14 | func TestVerify(t *testing.T) { 15 | pkFile, err := os.Open("../../../auth/public.key") 16 | if err != nil { 17 | logger.Fatal("cannot open public key", zap.Error(err)) 18 | } 19 | pkBytes, err := ioutil.ReadAll(pkFile) 20 | if err != nil { 21 | logger.Fatal("cannot read public key", zap.Error(err)) 22 | } 23 | pubKey, err := jwt.ParseRSAPublicKeyFromPEM([]byte(pkBytes)) 24 | if err != nil { 25 | t.Fatalf("cannot parse public key: %v", err) 26 | } 27 | 28 | v := &JWTTokenVerifier{ 29 | PublicKey: pubKey, 30 | } 31 | 32 | cases := []struct { 33 | name string 34 | tkn string 35 | now time.Time 36 | want string 37 | wantErr bool 38 | }{ 39 | { 40 | name: "valid_token", 41 | tkn: "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTYyNDYyMjIsImlhdCI6MTUxNjIzOTAyMiwiaXNzIjoiY29vbGNhci9hdXRoIiwic3ViIjoiNjA3MjY2YWE1MTJlMDA2ZDU4Yjc5ZDIyIn0.W1tkiBd3N-U3RM9b6OENFhYq9tp5PGjb2_V9nm1QvsjvCmmF5t2yyv70EkntPpIl5GErxZQd73zDSCQ0BSHHFOPmNYvUVar85DJS6KnvOTOIPmWrRkYmZqMAcWI4p9ifmh5X0J6KXkHrBgBqlcl_foU1xdt7M-VGl7BGZb8jMNCmAZYjOzpZeNFPt2fOX4JT1Vlhi02zpfSu0GRcxZvDmyqloTaGinUEL2rELIH53x05HhAbqPf_vuK2vjAIInKJQKd_ARhTM9xYDS3p0QBqsOsFJL8tRj5EY60NGROoZtCRPWbd2B757kUv5hsx72AF7PTvY0P_bRK6npG1PoPl2g", 42 | now: time.Unix(1516239122, 0), 43 | want: "607266aa512e006d58b79d22", 44 | }, 45 | { 46 | name: "token_expired", 47 | tkn: "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTYyNDYyMjIsImlhdCI6MTUxNjIzOTAyMiwiaXNzIjoiY29vbGNhci9hdXRoIiwic3ViIjoiNjA3MjY2YWE1MTJlMDA2ZDU4Yjc5ZDIyIn0.W1tkiBd3N-U3RM9b6OENFhYq9tp5PGjb2_V9nm1QvsjvCmmF5t2yyv70EkntPpIl5GErxZQd73zDSCQ0BSHHFOPmNYvUVar85DJS6KnvOTOIPmWrRkYmZqMAcWI4p9ifmh5X0J6KXkHrBgBqlcl_foU1xdt7M-VGl7BGZb8jMNCmAZYjOzpZeNFPt2fOX4JT1Vlhi02zpfSu0GRcxZvDmyqloTaGinUEL2rELIH53x05HhAbqPf_vuK2vjAIInKJQKd_ARhTM9xYDS3p0QBqsOsFJL8tRj5EY60NGROoZtCRPWbd2B757kUv5hsx72AF7PTvY0P_bRK6npG1PoPl2g", 48 | now: time.Unix(1517239122, 0), 49 | wantErr: true, 50 | }, 51 | { 52 | name: "bad_token", 53 | tkn: "bad_token", 54 | now: time.Unix(1517239122, 0), 55 | wantErr: true, 56 | }, 57 | { 58 | name: "wrong_signature", 59 | tkn: "eyJhbGciOiJSUzUxMiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE1MTYyNDYyMjIsImlhdCI6MTUxNjIzOTAyMiwiaXNzIjoiY29vbGNhci9hdXRoIiwic3ViIjoiNjA3MjY2YWE1MTJlMDA2ZDU4Yjc5ZDIzIn0.W1tkiBd3N-U3RM9b6OENFhYq9tp5PGjb2_V9nm1QvsjvCmmF5t2yyv70EkntPpIl5GErxZQd73zDSCQ0BSHHFOPmNYvUVar85DJS6KnvOTOIPmWrRkYmZqMAcWI4p9ifmh5X0J6KXkHrBgBqlcl_foU1xdt7M-VGl7BGZb8jMNCmAZYjOzpZeNFPt2fOX4JT1Vlhi02zpfSu0GRcxZvDmyqloTaGinUEL2rELIH53x05HhAbqPf_vuK2vjAIInKJQKd_ARhTM9xYDS3p0QBqsOsFJL8tRj5EY60NGROoZtCRPWbd2B757kUv5hsx72AF7PTvY0P_bRK6npG1PoPl2g", 60 | now: time.Unix(1516239122, 0), 61 | wantErr: true, 62 | }, 63 | } 64 | 65 | for _, c := range cases { 66 | t.Run(c.name, func(t *testing.T) { 67 | jwt.TimeFunc = func() time.Time { 68 | return c.now 69 | } 70 | 71 | accountID, err := v.Verify(c.tkn) 72 | 73 | if !c.wantErr && err != nil { 74 | t.Errorf("verification failed: %v", err) 75 | } 76 | 77 | if c.wantErr && err == nil { 78 | t.Errorf("want error; got no error") 79 | } 80 | 81 | if accountID != c.want { 82 | t.Errorf("wrong account id. want: %q, got: %q", c.want, accountID) 83 | } 84 | }) 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /microsvcs/auth/api/gen/v1/auth_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | 3 | package authpb 4 | 5 | import ( 6 | context "context" 7 | grpc "google.golang.org/grpc" 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | // This is a compile-time assertion to ensure that this generated file 13 | // is compatible with the grpc package it is being compiled against. 14 | // Requires gRPC-Go v1.32.0 or later. 15 | const _ = grpc.SupportPackageIsVersion7 16 | 17 | // AuthServiceClient is the client API for AuthService service. 18 | // 19 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 20 | type AuthServiceClient interface { 21 | Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) 22 | } 23 | 24 | type authServiceClient struct { 25 | cc grpc.ClientConnInterface 26 | } 27 | 28 | func NewAuthServiceClient(cc grpc.ClientConnInterface) AuthServiceClient { 29 | return &authServiceClient{cc} 30 | } 31 | 32 | func (c *authServiceClient) Login(ctx context.Context, in *LoginRequest, opts ...grpc.CallOption) (*LoginResponse, error) { 33 | out := new(LoginResponse) 34 | err := c.cc.Invoke(ctx, "/auth.v1.AuthService/Login", in, out, opts...) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return out, nil 39 | } 40 | 41 | // AuthServiceServer is the server API for AuthService service. 42 | // All implementations must embed UnimplementedAuthServiceServer 43 | // for forward compatibility 44 | type AuthServiceServer interface { 45 | Login(context.Context, *LoginRequest) (*LoginResponse, error) 46 | mustEmbedUnimplementedAuthServiceServer() 47 | } 48 | 49 | // UnimplementedAuthServiceServer must be embedded to have forward compatible implementations. 50 | type UnimplementedAuthServiceServer struct { 51 | } 52 | 53 | func (UnimplementedAuthServiceServer) Login(context.Context, *LoginRequest) (*LoginResponse, error) { 54 | return nil, status.Errorf(codes.Unimplemented, "method Login not implemented") 55 | } 56 | func (UnimplementedAuthServiceServer) mustEmbedUnimplementedAuthServiceServer() {} 57 | 58 | // UnsafeAuthServiceServer may be embedded to opt out of forward compatibility for this service. 59 | // Use of this interface is not recommended, as added methods to AuthServiceServer will 60 | // result in compilation errors. 61 | type UnsafeAuthServiceServer interface { 62 | mustEmbedUnimplementedAuthServiceServer() 63 | } 64 | 65 | func RegisterAuthServiceServer(s grpc.ServiceRegistrar, srv AuthServiceServer) { 66 | s.RegisterService(&AuthService_ServiceDesc, srv) 67 | } 68 | 69 | func _AuthService_Login_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 70 | in := new(LoginRequest) 71 | if err := dec(in); err != nil { 72 | return nil, err 73 | } 74 | if interceptor == nil { 75 | return srv.(AuthServiceServer).Login(ctx, in) 76 | } 77 | info := &grpc.UnaryServerInfo{ 78 | Server: srv, 79 | FullMethod: "/auth.v1.AuthService/Login", 80 | } 81 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 82 | return srv.(AuthServiceServer).Login(ctx, req.(*LoginRequest)) 83 | } 84 | return interceptor(ctx, in, info, handler) 85 | } 86 | 87 | // AuthService_ServiceDesc is the grpc.ServiceDesc for AuthService service. 88 | // It's only intended for direct use with grpc.RegisterService, 89 | // and not to be introspected or modified (even as a copy) 90 | var AuthService_ServiceDesc = grpc.ServiceDesc{ 91 | ServiceName: "auth.v1.AuthService", 92 | HandlerType: (*AuthServiceServer)(nil), 93 | Methods: []grpc.MethodDesc{ 94 | { 95 | MethodName: "Login", 96 | Handler: _AuthService_Login_Handler, 97 | }, 98 | }, 99 | Streams: []grpc.StreamDesc{}, 100 | Metadata: "auth.proto", 101 | } 102 | -------------------------------------------------------------------------------- /microsvcs/todo/api/gen/v1/todo_grpc.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go-grpc. DO NOT EDIT. 2 | 3 | package todopb 4 | 5 | import ( 6 | context "context" 7 | grpc "google.golang.org/grpc" 8 | codes "google.golang.org/grpc/codes" 9 | status "google.golang.org/grpc/status" 10 | ) 11 | 12 | // This is a compile-time assertion to ensure that this generated file 13 | // is compatible with the grpc package it is being compiled against. 14 | // Requires gRPC-Go v1.32.0 or later. 15 | const _ = grpc.SupportPackageIsVersion7 16 | 17 | // TodoServiceClient is the client API for TodoService service. 18 | // 19 | // For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream. 20 | type TodoServiceClient interface { 21 | CreateTodo(ctx context.Context, in *CreateTodoRequest, opts ...grpc.CallOption) (*CreateTodoResponse, error) 22 | } 23 | 24 | type todoServiceClient struct { 25 | cc grpc.ClientConnInterface 26 | } 27 | 28 | func NewTodoServiceClient(cc grpc.ClientConnInterface) TodoServiceClient { 29 | return &todoServiceClient{cc} 30 | } 31 | 32 | func (c *todoServiceClient) CreateTodo(ctx context.Context, in *CreateTodoRequest, opts ...grpc.CallOption) (*CreateTodoResponse, error) { 33 | out := new(CreateTodoResponse) 34 | err := c.cc.Invoke(ctx, "/todo.v1.TodoService/CreateTodo", in, out, opts...) 35 | if err != nil { 36 | return nil, err 37 | } 38 | return out, nil 39 | } 40 | 41 | // TodoServiceServer is the server API for TodoService service. 42 | // All implementations must embed UnimplementedTodoServiceServer 43 | // for forward compatibility 44 | type TodoServiceServer interface { 45 | CreateTodo(context.Context, *CreateTodoRequest) (*CreateTodoResponse, error) 46 | mustEmbedUnimplementedTodoServiceServer() 47 | } 48 | 49 | // UnimplementedTodoServiceServer must be embedded to have forward compatible implementations. 50 | type UnimplementedTodoServiceServer struct { 51 | } 52 | 53 | func (UnimplementedTodoServiceServer) CreateTodo(context.Context, *CreateTodoRequest) (*CreateTodoResponse, error) { 54 | return nil, status.Errorf(codes.Unimplemented, "method CreateTodo not implemented") 55 | } 56 | func (UnimplementedTodoServiceServer) mustEmbedUnimplementedTodoServiceServer() {} 57 | 58 | // UnsafeTodoServiceServer may be embedded to opt out of forward compatibility for this service. 59 | // Use of this interface is not recommended, as added methods to TodoServiceServer will 60 | // result in compilation errors. 61 | type UnsafeTodoServiceServer interface { 62 | mustEmbedUnimplementedTodoServiceServer() 63 | } 64 | 65 | func RegisterTodoServiceServer(s grpc.ServiceRegistrar, srv TodoServiceServer) { 66 | s.RegisterService(&TodoService_ServiceDesc, srv) 67 | } 68 | 69 | func _TodoService_CreateTodo_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { 70 | in := new(CreateTodoRequest) 71 | if err := dec(in); err != nil { 72 | return nil, err 73 | } 74 | if interceptor == nil { 75 | return srv.(TodoServiceServer).CreateTodo(ctx, in) 76 | } 77 | info := &grpc.UnaryServerInfo{ 78 | Server: srv, 79 | FullMethod: "/todo.v1.TodoService/CreateTodo", 80 | } 81 | handler := func(ctx context.Context, req interface{}) (interface{}, error) { 82 | return srv.(TodoServiceServer).CreateTodo(ctx, req.(*CreateTodoRequest)) 83 | } 84 | return interceptor(ctx, in, info, handler) 85 | } 86 | 87 | // TodoService_ServiceDesc is the grpc.ServiceDesc for TodoService service. 88 | // It's only intended for direct use with grpc.RegisterService, 89 | // and not to be introspected or modified (even as a copy) 90 | var TodoService_ServiceDesc = grpc.ServiceDesc{ 91 | ServiceName: "todo.v1.TodoService", 92 | HandlerType: (*TodoServiceServer)(nil), 93 | Methods: []grpc.MethodDesc{ 94 | { 95 | MethodName: "CreateTodo", 96 | Handler: _TodoService_CreateTodo_Handler, 97 | }, 98 | }, 99 | Streams: []grpc.StreamDesc{}, 100 | Metadata: "todo.proto", 101 | } 102 | -------------------------------------------------------------------------------- /client/miniprogram/service/sdk.ts: -------------------------------------------------------------------------------- 1 | 2 | import camelcaseKeys = require("camelcase-keys") 3 | import { auth } from "./proto_gen/auth/auth_pb" 4 | export namespace SDK { 5 | const serverAddr = 'http://localhost:8080' 6 | const AUTH_ERR= 'AUTH_ERR' 7 | 8 | const authData = { 9 | token: '', 10 | expiryMs: 0 11 | } 12 | 13 | export interface RequestOption { 14 | method: 'GET'|'PUT'|'POST'|'DELETE' 15 | path: string 16 | data: REQ 17 | respMarshaller: (r: object)=>RES 18 | } 19 | 20 | export interface AuthOption { 21 | attachAuthHeader: boolean 22 | retryOnAuthError: boolean 23 | } 24 | 25 | export async function sendRequestWithAuthRetry(o: RequestOption, a?: AuthOption): Promise { 26 | const authOpt = a || { 27 | attachAuthHeader: true, 28 | retryOnAuthError: true, 29 | } 30 | try { 31 | await login() 32 | return sendRequest(o, authOpt) 33 | } catch(err) { 34 | if(err === AUTH_ERR && authOpt.retryOnAuthError) { 35 | authData.token = '' 36 | authData.expiryMs = 0 37 | return sendRequestWithAuthRetry(o, { 38 | attachAuthHeader: authOpt.attachAuthHeader, 39 | retryOnAuthError: false 40 | }) 41 | } else { 42 | throw err 43 | } 44 | } 45 | } 46 | 47 | export async function login() { 48 | if (authData.token && authData.expiryMs >= Date.now()) { 49 | return 50 | } 51 | const wxResp = await wxLogin() 52 | const reqTimeMs = Date.now() 53 | const resp = await sendRequest({ 54 | method: "POST", 55 | path: "/v1/auth/login", 56 | data: { 57 | code: wxResp.code, 58 | }, 59 | respMarshaller: auth.v1.LoginResponse.fromObject 60 | }, { 61 | attachAuthHeader: false, 62 | retryOnAuthError: false, 63 | }) 64 | authData.token = resp.accessToken! 65 | authData.expiryMs = reqTimeMs + resp.expiresIn! * 1000 66 | } 67 | 68 | export function sendRequest(o: RequestOption, a: AuthOption): Promise { 69 | const authOpt = a || { 70 | attachAuthHeader: true, 71 | } 72 | return new Promise((resolve, reject) => { 73 | const header: Record = {} 74 | if (authOpt.attachAuthHeader) { 75 | if (authData.token && authData.expiryMs >= Date.now()) { 76 | header.authorization = 'Bearer '+ authData.token 77 | } else { 78 | reject(AUTH_ERR) 79 | return 80 | } 81 | } 82 | wx.request({ 83 | url: serverAddr + o.path, 84 | method: o.method, 85 | data: o.data, 86 | header, 87 | success: res => { 88 | if(res.statusCode === 401) { 89 | reject(AUTH_ERR) 90 | } else if (res.statusCode >= 400) { 91 | reject(res) 92 | } else { 93 | resolve( 94 | o.respMarshaller( 95 | camelcaseKeys(res.data as object, { deep: true }), 96 | ) 97 | ) 98 | } 99 | }, 100 | fail: reject 101 | }) 102 | }) 103 | } 104 | 105 | export function wxLogin(): Promise { 106 | return new Promise((resolve, reject) => { 107 | wx.login({ 108 | success: resolve, 109 | fail: reject, 110 | }) 111 | }) 112 | } 113 | } -------------------------------------------------------------------------------- /client/miniprogram/pages/index/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var app = getApp(); 3 | Page({ 4 | data: { 5 | motto: '公众号:黑客下午茶', 6 | userInfo: {}, 7 | hasUserInfo: false, 8 | canIUse: wx.canIUse('button.open-type.getUserInfo'), 9 | canIUseGetUserProfile: false, 10 | canIUseOpenData: wx.canIUse('open-data.type.userAvatarUrl') && wx.canIUse('open-data.type.userNickName') 11 | }, 12 | bindViewTap: function () { 13 | wx.navigateTo({ 14 | url: '../logs/logs', 15 | }); 16 | }, 17 | onLoad: function () { 18 | if (wx.getUserProfile) { 19 | this.setData({ 20 | canIUseGetUserProfile: true 21 | }); 22 | } 23 | }, 24 | getUserProfile: function () { 25 | var _this = this; 26 | wx.getUserProfile({ 27 | desc: '展示用户信息', 28 | success: function (res) { 29 | console.log(res); 30 | _this.setData({ 31 | userInfo: res.userInfo, 32 | hasUserInfo: true 33 | }); 34 | } 35 | }); 36 | }, 37 | getUserInfo: function (e) { 38 | console.log(e); 39 | this.setData({ 40 | userInfo: e.detail.userInfo, 41 | hasUserInfo: true 42 | }); 43 | } 44 | }); 45 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBRUEsSUFBTSxHQUFHLEdBQUcsTUFBTSxFQUFjLENBQUE7QUFFaEMsSUFBSSxDQUFDO0lBQ0gsSUFBSSxFQUFFO1FBQ0osS0FBSyxFQUFFLFdBQVc7UUFDbEIsUUFBUSxFQUFFLEVBQUU7UUFDWixXQUFXLEVBQUUsS0FBSztRQUNsQixPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyw4QkFBOEIsQ0FBQztRQUNuRCxxQkFBcUIsRUFBRSxLQUFLO1FBQzVCLGVBQWUsRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLDhCQUE4QixDQUFDLElBQUksRUFBRSxDQUFDLE9BQU8sQ0FBQyw2QkFBNkIsQ0FBQztLQUN6RztJQUVELFdBQVc7UUFDVCxFQUFFLENBQUMsVUFBVSxDQUFDO1lBQ1osR0FBRyxFQUFFLGNBQWM7U0FDcEIsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUNELE1BQU07UUFFSixJQUFJLEVBQUUsQ0FBQyxjQUFjLEVBQUU7WUFDckIsSUFBSSxDQUFDLE9BQU8sQ0FBQztnQkFDWCxxQkFBcUIsRUFBRSxJQUFJO2FBQzVCLENBQUMsQ0FBQTtTQUNIO0lBQ0gsQ0FBQztJQUNELGNBQWM7UUFBZCxpQkFZQztRQVZDLEVBQUUsQ0FBQyxjQUFjLENBQUM7WUFDaEIsSUFBSSxFQUFFLFFBQVE7WUFDZCxPQUFPLEVBQUUsVUFBQyxHQUFHO2dCQUNYLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUE7Z0JBQ2hCLEtBQUksQ0FBQyxPQUFPLENBQUM7b0JBQ1gsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRO29CQUN0QixXQUFXLEVBQUUsSUFBSTtpQkFDbEIsQ0FBQyxDQUFBO1lBQ0osQ0FBQztTQUNGLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFDRCxXQUFXLEVBQVgsVUFBWSxDQUFNO1FBRWhCLE9BQU8sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDZCxJQUFJLENBQUMsT0FBTyxDQUFDO1lBQ1gsUUFBUSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUTtZQUMzQixXQUFXLEVBQUUsSUFBSTtTQUNsQixDQUFDLENBQUE7SUFDSixDQUFDO0NBQ0YsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiLy8gaW5kZXgudHNcbi8vIOiOt+WPluW6lOeUqOWunuS+i1xuY29uc3QgYXBwID0gZ2V0QXBwPElBcHBPcHRpb24+KClcblxuUGFnZSh7XG4gIGRhdGE6IHtcbiAgICBtb3R0bzogJ+WFrOS8l+WPt++8mum7keWuouS4i+WNiOiMticsXG4gICAgdXNlckluZm86IHt9LFxuICAgIGhhc1VzZXJJbmZvOiBmYWxzZSxcbiAgICBjYW5JVXNlOiB3eC5jYW5JVXNlKCdidXR0b24ub3Blbi10eXBlLmdldFVzZXJJbmZvJyksXG4gICAgY2FuSVVzZUdldFVzZXJQcm9maWxlOiBmYWxzZSxcbiAgICBjYW5JVXNlT3BlbkRhdGE6IHd4LmNhbklVc2UoJ29wZW4tZGF0YS50eXBlLnVzZXJBdmF0YXJVcmwnKSAmJiB3eC5jYW5JVXNlKCdvcGVuLWRhdGEudHlwZS51c2VyTmlja05hbWUnKSAvLyDlpoLpnIDlsJ3or5Xojrflj5bnlKjmiLfkv6Hmga/lj6/mlLnkuLpmYWxzZVxuICB9LFxuICAvLyDkuovku7blpITnkIblh73mlbBcbiAgYmluZFZpZXdUYXAoKSB7XG4gICAgd3gubmF2aWdhdGVUbyh7XG4gICAgICB1cmw6ICcuLi9sb2dzL2xvZ3MnLFxuICAgIH0pXG4gIH0sXG4gIG9uTG9hZCgpIHtcbiAgICAvLyBAdHMtaWdub3JlXG4gICAgaWYgKHd4LmdldFVzZXJQcm9maWxlKSB7XG4gICAgICB0aGlzLnNldERhdGEoe1xuICAgICAgICBjYW5JVXNlR2V0VXNlclByb2ZpbGU6IHRydWVcbiAgICAgIH0pXG4gICAgfVxuICB9LFxuICBnZXRVc2VyUHJvZmlsZSgpIHtcbiAgICAvLyDmjqjojZDkvb/nlKh3eC5nZXRVc2VyUHJvZmlsZeiOt+WPlueUqOaIt+S/oeaBr++8jOW8gOWPkeiAheavj+asoemAmui/h+ivpeaOpeWPo+iOt+WPlueUqOaIt+S4quS6uuS/oeaBr+Wdh+mcgOeUqOaIt+ehruiupO+8jOW8gOWPkeiAheWmpeWWhOS/neeuoeeUqOaIt+W/q+mAn+Whq+WGmeeahOWktOWDj+aYteensO+8jOmBv+WFjemHjeWkjeW8ueeql1xuICAgIHd4LmdldFVzZXJQcm9maWxlKHtcbiAgICAgIGRlc2M6ICflsZXnpLrnlKjmiLfkv6Hmga8nLCAvLyDlo7DmmI7ojrflj5bnlKjmiLfkuKrkurrkv6Hmga/lkI7nmoTnlKjpgJTvvIzlkI7nu63kvJrlsZXnpLrlnKjlvLnnqpfkuK3vvIzor7fosKjmhY7loavlhplcbiAgICAgIHN1Y2Nlc3M6IChyZXMpID0+IHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzKVxuICAgICAgICB0aGlzLnNldERhdGEoe1xuICAgICAgICAgIHVzZXJJbmZvOiByZXMudXNlckluZm8sXG4gICAgICAgICAgaGFzVXNlckluZm86IHRydWVcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9KVxuICB9LFxuICBnZXRVc2VySW5mbyhlOiBhbnkpIHtcbiAgICAvLyDkuI3mjqjojZDkvb/nlKhnZXRVc2VySW5mb+iOt+WPlueUqOaIt+S/oeaBr++8jOmihOiuoeiHqjIwMjHlubQ05pyIMTPml6XotbfvvIxnZXRVc2VySW5mb+WwhuS4jeWGjeW8ueWHuuW8ueeql++8jOW5tuebtOaOpei/lOWbnuWMv+WQjeeahOeUqOaIt+S4quS6uuS/oeaBr1xuICAgIGNvbnNvbGUubG9nKGUpXG4gICAgdGhpcy5zZXREYXRhKHtcbiAgICAgIHVzZXJJbmZvOiBlLmRldGFpbC51c2VySW5mbyxcbiAgICAgIGhhc1VzZXJJbmZvOiB0cnVlXG4gICAgfSlcbiAgfVxufSlcbiJdfQ== -------------------------------------------------------------------------------- /client/miniprogram/app.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | Object.defineProperty(exports, "__esModule", { value: true }); 3 | var camelcaseKeys = require("camelcase-keys"); 4 | var auth_pb_1 = require("./service/proto_gen/auth/auth_pb"); 5 | App({ 6 | globalData: {}, 7 | onLaunch: function () { 8 | var logs = wx.getStorageSync('logs') || []; 9 | logs.unshift(Date.now()); 10 | wx.setStorageSync('logs', logs); 11 | wx.login({ 12 | success: function (res) { 13 | console.log(res.code); 14 | wx.request({ 15 | url: "http://localhost:8080/v1/auth/login", 16 | method: "POST", 17 | data: { 18 | code: res.code 19 | }, 20 | success: function (res) { 21 | var loginResp = auth_pb_1.auth.v1.LoginResponse.fromObject(camelcaseKeys(res.data)); 22 | console.log(loginResp); 23 | wx.request({ 24 | url: "http://localhost:8080/v1/todo", 25 | method: "POST", 26 | data: { 27 | title: "hello,world!" 28 | }, 29 | header: { 30 | authorization: 'Bearer ' + loginResp.accessToken, 31 | } 32 | }); 33 | }, 34 | fail: console.error, 35 | }); 36 | }, 37 | }); 38 | }, 39 | }); 40 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYXBwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsOENBQStDO0FBQy9DLDREQUF1RDtBQUd2RCxHQUFHLENBQWE7SUFDZCxVQUFVLEVBQUUsRUFBRTtJQUNkLFFBQVEsRUFBUjtRQUVFLElBQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQzVDLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUE7UUFDeEIsRUFBRSxDQUFDLGNBQWMsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLENBQUE7UUFHL0IsRUFBRSxDQUFDLEtBQUssQ0FBQztZQUNQLE9BQU8sRUFBRSxVQUFBLEdBQUc7Z0JBQ1YsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUE7Z0JBQ3JCLEVBQUUsQ0FBQyxPQUFPLENBQUM7b0JBQ1QsR0FBRyxFQUFFLHFDQUFxQztvQkFDMUMsTUFBTSxFQUFFLE1BQU07b0JBQ2QsSUFBSSxFQUFFO3dCQUNKLElBQUksRUFBRSxHQUFHLENBQUMsSUFBSTtxQkFDVTtvQkFDMUIsT0FBTyxFQUFFLFVBQUEsR0FBRzt3QkFDVixJQUFNLFNBQVMsR0FDYixjQUFJLENBQUMsRUFBRSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQzlCLGFBQWEsQ0FBQyxHQUFHLENBQUMsSUFBYyxDQUFDLENBQ2xDLENBQUE7d0JBQ0gsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQTt3QkFHdEIsRUFBRSxDQUFDLE9BQU8sQ0FBQzs0QkFDVCxHQUFHLEVBQUUsK0JBQStCOzRCQUNwQyxNQUFNLEVBQUUsTUFBTTs0QkFDZCxJQUFJLEVBQUU7Z0NBQ0osS0FBSyxFQUFFLGNBQWM7NkJBQ1E7NEJBQy9CLE1BQU0sRUFBRTtnQ0FDTixhQUFhLEVBQUUsU0FBUyxHQUFDLFNBQVMsQ0FBQyxXQUFXOzZCQUMvQzt5QkFDRixDQUFDLENBQUE7b0JBQ0osQ0FBQztvQkFDRCxJQUFJLEVBQUUsT0FBTyxDQUFDLEtBQUs7aUJBQ3BCLENBQUMsQ0FBQTtZQUNKLENBQUM7U0FDRixDQUFDLENBQUE7SUFDSixDQUFDO0NBQ0YsQ0FBQyxDQUFBIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY2FtZWxjYXNlS2V5cyBmcm9tIFwiY2FtZWxjYXNlLWtleXNcIlxuaW1wb3J0IHsgYXV0aCB9IGZyb20gXCIuL3NlcnZpY2UvcHJvdG9fZ2VuL2F1dGgvYXV0aF9wYlwiXG5pbXBvcnQgeyB0b2RvIH0gZnJvbSBcIi4vc2VydmljZS9wcm90b19nZW4vdG9kby90b2RvX3BiXCJcbi8vIGFwcC50c1xuQXBwPElBcHBPcHRpb24+KHtcbiAgZ2xvYmFsRGF0YToge30sXG4gIG9uTGF1bmNoKCkge1xuICAgIC8vIOWxleekuuacrOWcsOWtmOWCqOiDveWKm1xuICAgIGNvbnN0IGxvZ3MgPSB3eC5nZXRTdG9yYWdlU3luYygnbG9ncycpIHx8IFtdXG4gICAgbG9ncy51bnNoaWZ0KERhdGUubm93KCkpXG4gICAgd3guc2V0U3RvcmFnZVN5bmMoJ2xvZ3MnLCBsb2dzKVxuXG4gICAgLy8g55m75b2VXG4gICAgd3gubG9naW4oe1xuICAgICAgc3VjY2VzczogcmVzID0+IHtcbiAgICAgICAgY29uc29sZS5sb2cocmVzLmNvZGUpXG4gICAgICAgIHd4LnJlcXVlc3Qoe1xuICAgICAgICAgIHVybDogXCJodHRwOi8vbG9jYWxob3N0OjgwODAvdjEvYXV0aC9sb2dpblwiLFxuICAgICAgICAgIG1ldGhvZDogXCJQT1NUXCIsXG4gICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgY29kZTogcmVzLmNvZGVcbiAgICAgICAgICB9IGFzIGF1dGgudjEuSUxvZ2luUmVxdWVzdCxcbiAgICAgICAgICBzdWNjZXNzOiByZXMgPT4ge1xuICAgICAgICAgICAgY29uc3QgbG9naW5SZXNwOiBhdXRoLnYxLklMb2dpblJlc3BvbnNlID0gXG4gICAgICAgICAgICAgIGF1dGgudjEuTG9naW5SZXNwb25zZS5mcm9tT2JqZWN0KFxuICAgICAgICAgICAgICAgIGNhbWVsY2FzZUtleXMocmVzLmRhdGEgYXMgb2JqZWN0KSxcbiAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgY29uc29sZS5sb2cobG9naW5SZXNwKVxuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyDmtYvor5XmjqXlj6NcbiAgICAgICAgICAgIHd4LnJlcXVlc3Qoe1xuICAgICAgICAgICAgICB1cmw6IFwiaHR0cDovL2xvY2FsaG9zdDo4MDgwL3YxL3RvZG9cIixcbiAgICAgICAgICAgICAgbWV0aG9kOiBcIlBPU1RcIixcbiAgICAgICAgICAgICAgZGF0YToge1xuICAgICAgICAgICAgICAgIHRpdGxlOiBcImhlbGxvLHdvcmxkIVwiXG4gICAgICAgICAgICAgIH0gYXMgdG9kby52MS5JQ3JlYXRlVG9kb1JlcXVlc3QsXG4gICAgICAgICAgICAgIGhlYWRlcjoge1xuICAgICAgICAgICAgICAgIGF1dGhvcml6YXRpb246ICdCZWFyZXIgJytsb2dpblJlc3AuYWNjZXNzVG9rZW4sXG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfSxcbiAgICAgICAgICBmYWlsOiBjb25zb2xlLmVycm9yLFxuICAgICAgICB9KVxuICAgICAgfSxcbiAgICB9KVxuICB9LFxufSkiXX0= -------------------------------------------------------------------------------- /client/miniprogram/service/proto_gen/todo/todo_pb.d.ts: -------------------------------------------------------------------------------- 1 | import * as $protobuf from "protobufjs"; 2 | /** Namespace todo. */ 3 | export namespace todo { 4 | 5 | /** Namespace v1. */ 6 | namespace v1 { 7 | 8 | /** Properties of a CreateTodoRequest. */ 9 | interface ICreateTodoRequest { 10 | 11 | /** CreateTodoRequest title */ 12 | title?: (string|null); 13 | } 14 | 15 | /** Represents a CreateTodoRequest. */ 16 | class CreateTodoRequest implements ICreateTodoRequest { 17 | 18 | /** 19 | * Constructs a new CreateTodoRequest. 20 | * @param [properties] Properties to set 21 | */ 22 | constructor(properties?: todo.v1.ICreateTodoRequest); 23 | 24 | /** CreateTodoRequest title. */ 25 | public title: string; 26 | 27 | /** 28 | * Creates a CreateTodoRequest message from a plain object. Also converts values to their respective internal types. 29 | * @param object Plain object 30 | * @returns CreateTodoRequest 31 | */ 32 | public static fromObject(object: { [k: string]: any }): todo.v1.CreateTodoRequest; 33 | 34 | /** 35 | * Creates a plain object from a CreateTodoRequest message. Also converts values to other types if specified. 36 | * @param message CreateTodoRequest 37 | * @param [options] Conversion options 38 | * @returns Plain object 39 | */ 40 | public static toObject(message: todo.v1.CreateTodoRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; 41 | 42 | /** 43 | * Converts this CreateTodoRequest to JSON. 44 | * @returns JSON object 45 | */ 46 | public toJSON(): { [k: string]: any }; 47 | } 48 | 49 | /** Properties of a CreateTodoResponse. */ 50 | interface ICreateTodoResponse { 51 | } 52 | 53 | /** Represents a CreateTodoResponse. */ 54 | class CreateTodoResponse implements ICreateTodoResponse { 55 | 56 | /** 57 | * Constructs a new CreateTodoResponse. 58 | * @param [properties] Properties to set 59 | */ 60 | constructor(properties?: todo.v1.ICreateTodoResponse); 61 | 62 | /** 63 | * Creates a CreateTodoResponse message from a plain object. Also converts values to their respective internal types. 64 | * @param object Plain object 65 | * @returns CreateTodoResponse 66 | */ 67 | public static fromObject(object: { [k: string]: any }): todo.v1.CreateTodoResponse; 68 | 69 | /** 70 | * Creates a plain object from a CreateTodoResponse message. Also converts values to other types if specified. 71 | * @param message CreateTodoResponse 72 | * @param [options] Conversion options 73 | * @returns Plain object 74 | */ 75 | public static toObject(message: todo.v1.CreateTodoResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; 76 | 77 | /** 78 | * Converts this CreateTodoResponse to JSON. 79 | * @returns JSON object 80 | */ 81 | public toJSON(): { [k: string]: any }; 82 | } 83 | 84 | /** Represents a TodoService */ 85 | class TodoService extends $protobuf.rpc.Service { 86 | 87 | /** 88 | * Constructs a new TodoService service. 89 | * @param rpcImpl RPC implementation 90 | * @param [requestDelimited=false] Whether requests are length-delimited 91 | * @param [responseDelimited=false] Whether responses are length-delimited 92 | */ 93 | constructor(rpcImpl: $protobuf.RPCImpl, requestDelimited?: boolean, responseDelimited?: boolean); 94 | 95 | /** 96 | * Calls CreateTodo. 97 | * @param request CreateTodoRequest message or plain object 98 | * @param callback Node-style callback called with the error, if any, and CreateTodoResponse 99 | */ 100 | public createTodo(request: todo.v1.ICreateTodoRequest, callback: todo.v1.TodoService.CreateTodoCallback): void; 101 | 102 | /** 103 | * Calls CreateTodo. 104 | * @param request CreateTodoRequest message or plain object 105 | * @returns Promise 106 | */ 107 | public createTodo(request: todo.v1.ICreateTodoRequest): Promise; 108 | } 109 | 110 | namespace TodoService { 111 | 112 | /** 113 | * Callback as used by {@link todo.v1.TodoService#createTodo}. 114 | * @param error Error, if any 115 | * @param [response] CreateTodoResponse 116 | */ 117 | type CreateTodoCallback = (error: (Error|null), response?: todo.v1.CreateTodoResponse) => void; 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /client/miniprogram/service/proto_gen/auth/auth_pb.d.ts: -------------------------------------------------------------------------------- 1 | import * as $protobuf from "protobufjs"; 2 | /** Namespace auth. */ 3 | export namespace auth { 4 | 5 | /** Namespace v1. */ 6 | namespace v1 { 7 | 8 | /** Properties of a LoginRequest. */ 9 | interface ILoginRequest { 10 | 11 | /** LoginRequest code */ 12 | code?: (string|null); 13 | } 14 | 15 | /** Represents a LoginRequest. */ 16 | class LoginRequest implements ILoginRequest { 17 | 18 | /** 19 | * Constructs a new LoginRequest. 20 | * @param [properties] Properties to set 21 | */ 22 | constructor(properties?: auth.v1.ILoginRequest); 23 | 24 | /** LoginRequest code. */ 25 | public code: string; 26 | 27 | /** 28 | * Creates a LoginRequest message from a plain object. Also converts values to their respective internal types. 29 | * @param object Plain object 30 | * @returns LoginRequest 31 | */ 32 | public static fromObject(object: { [k: string]: any }): auth.v1.LoginRequest; 33 | 34 | /** 35 | * Creates a plain object from a LoginRequest message. Also converts values to other types if specified. 36 | * @param message LoginRequest 37 | * @param [options] Conversion options 38 | * @returns Plain object 39 | */ 40 | public static toObject(message: auth.v1.LoginRequest, options?: $protobuf.IConversionOptions): { [k: string]: any }; 41 | 42 | /** 43 | * Converts this LoginRequest to JSON. 44 | * @returns JSON object 45 | */ 46 | public toJSON(): { [k: string]: any }; 47 | } 48 | 49 | /** Properties of a LoginResponse. */ 50 | interface ILoginResponse { 51 | 52 | /** LoginResponse accessToken */ 53 | accessToken?: (string|null); 54 | 55 | /** LoginResponse expiresIn */ 56 | expiresIn?: (number|null); 57 | } 58 | 59 | /** Represents a LoginResponse. */ 60 | class LoginResponse implements ILoginResponse { 61 | 62 | /** 63 | * Constructs a new LoginResponse. 64 | * @param [properties] Properties to set 65 | */ 66 | constructor(properties?: auth.v1.ILoginResponse); 67 | 68 | /** LoginResponse accessToken. */ 69 | public accessToken: string; 70 | 71 | /** LoginResponse expiresIn. */ 72 | public expiresIn: number; 73 | 74 | /** 75 | * Creates a LoginResponse message from a plain object. Also converts values to their respective internal types. 76 | * @param object Plain object 77 | * @returns LoginResponse 78 | */ 79 | public static fromObject(object: { [k: string]: any }): auth.v1.LoginResponse; 80 | 81 | /** 82 | * Creates a plain object from a LoginResponse message. Also converts values to other types if specified. 83 | * @param message LoginResponse 84 | * @param [options] Conversion options 85 | * @returns Plain object 86 | */ 87 | public static toObject(message: auth.v1.LoginResponse, options?: $protobuf.IConversionOptions): { [k: string]: any }; 88 | 89 | /** 90 | * Converts this LoginResponse to JSON. 91 | * @returns JSON object 92 | */ 93 | public toJSON(): { [k: string]: any }; 94 | } 95 | 96 | /** Represents an AuthService */ 97 | class AuthService extends $protobuf.rpc.Service { 98 | 99 | /** 100 | * Constructs a new AuthService service. 101 | * @param rpcImpl RPC implementation 102 | * @param [requestDelimited=false] Whether requests are length-delimited 103 | * @param [responseDelimited=false] Whether responses are length-delimited 104 | */ 105 | constructor(rpcImpl: $protobuf.RPCImpl, requestDelimited?: boolean, responseDelimited?: boolean); 106 | 107 | /** 108 | * Calls Login. 109 | * @param request LoginRequest message or plain object 110 | * @param callback Node-style callback called with the error, if any, and LoginResponse 111 | */ 112 | public login(request: auth.v1.ILoginRequest, callback: auth.v1.AuthService.LoginCallback): void; 113 | 114 | /** 115 | * Calls Login. 116 | * @param request LoginRequest message or plain object 117 | * @returns Promise 118 | */ 119 | public login(request: auth.v1.ILoginRequest): Promise; 120 | } 121 | 122 | namespace AuthService { 123 | 124 | /** 125 | * Callback as used by {@link auth.v1.AuthService#login}. 126 | * @param error Error, if any 127 | * @param [response] LoginResponse 128 | */ 129 | type LoginCallback = (error: (Error|null), response?: auth.v1.LoginResponse) => void; 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /client/miniprogram/yarn.lock: -------------------------------------------------------------------------------- 1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. 2 | # yarn lockfile v1 3 | 4 | 5 | "@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2": 6 | version "1.1.2" 7 | resolved "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf" 8 | integrity sha1-m4sMxmPWaafY9vXQiToU00jzD78= 9 | 10 | "@protobufjs/base64@^1.1.2": 11 | version "1.1.2" 12 | resolved "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz#4c85730e59b9a1f1f349047dbf24296034bb2735" 13 | integrity sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg== 14 | 15 | "@protobufjs/codegen@^2.0.4": 16 | version "2.0.4" 17 | resolved "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz#7ef37f0d010fb028ad1ad59722e506d9262815cb" 18 | integrity sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg== 19 | 20 | "@protobufjs/eventemitter@^1.1.0": 21 | version "1.1.0" 22 | resolved "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz#355cbc98bafad5978f9ed095f397621f1d066b70" 23 | integrity sha1-NVy8mLr61ZePntCV85diHx0Ga3A= 24 | 25 | "@protobufjs/fetch@^1.1.0": 26 | version "1.1.0" 27 | resolved "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz#ba99fb598614af65700c1619ff06d454b0d84c45" 28 | integrity sha1-upn7WYYUr2VwDBYZ/wbUVLDYTEU= 29 | dependencies: 30 | "@protobufjs/aspromise" "^1.1.1" 31 | "@protobufjs/inquire" "^1.1.0" 32 | 33 | "@protobufjs/float@^1.0.2": 34 | version "1.0.2" 35 | resolved "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz#5e9e1abdcb73fc0a7cb8b291df78c8cbd97b87d1" 36 | integrity sha1-Xp4avctz/Ap8uLKR33jIy9l7h9E= 37 | 38 | "@protobufjs/inquire@^1.1.0": 39 | version "1.1.0" 40 | resolved "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz#ff200e3e7cf2429e2dcafc1140828e8cc638f089" 41 | integrity sha1-/yAOPnzyQp4tyvwRQIKOjMY48Ik= 42 | 43 | "@protobufjs/path@^1.1.2": 44 | version "1.1.2" 45 | resolved "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz#6cc2b20c5c9ad6ad0dccfd21ca7673d8d7fbf68d" 46 | integrity sha1-bMKyDFya1q0NzP0hynZz2Nf79o0= 47 | 48 | "@protobufjs/pool@^1.1.0": 49 | version "1.1.0" 50 | resolved "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz#09fd15f2d6d3abfa9b65bc366506d6ad7846ff54" 51 | integrity sha1-Cf0V8tbTq/qbZbw2ZQbWrXhG/1Q= 52 | 53 | "@protobufjs/utf8@^1.1.0": 54 | version "1.1.0" 55 | resolved "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" 56 | integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= 57 | 58 | "@types/long@^4.0.1": 59 | version "4.0.1" 60 | resolved "https://registry.npmjs.org/@types/long/-/long-4.0.1.tgz#459c65fa1867dafe6a8f322c4c51695663cc55e9" 61 | integrity sha512-5tXH6Bx/kNGd3MgffdmP4dy2Z+G4eaXw0SE81Tq3BNadtnMR5/ySMzX4SLEzHJzSmPNn4HIdpQsBvXMUykr58w== 62 | 63 | "@types/node@^13.7.0": 64 | version "13.13.48" 65 | resolved "https://registry.npmjs.org/@types/node/-/node-13.13.48.tgz#46a3df718aed5217277f2395a682e055a487e341" 66 | integrity sha512-z8wvSsgWQzkr4sVuMEEOvwMdOQjiRY2Y/ZW4fDfjfe3+TfQrZqFKOthBgk2RnVEmtOKrkwdZ7uTvsxTBLjKGDQ== 67 | 68 | camelcase-keys@^6.2.2: 69 | version "6.2.2" 70 | resolved "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz#5e755d6ba51aa223ec7d3d52f25778210f9dc3c0" 71 | integrity sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg== 72 | dependencies: 73 | camelcase "^5.3.1" 74 | map-obj "^4.0.0" 75 | quick-lru "^4.0.1" 76 | 77 | camelcase@^5.3.1: 78 | version "5.3.1" 79 | resolved "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz#e3c9b31569e106811df242f715725a1f4c494320" 80 | integrity sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg== 81 | 82 | long@^4.0.0: 83 | version "4.0.0" 84 | resolved "https://registry.npmjs.org/long/-/long-4.0.0.tgz#9a7b71cfb7d361a194ea555241c92f7468d5bf28" 85 | integrity sha512-XsP+KhQif4bjX1kbuSiySJFNAehNxgLb6hPRGJ9QsUr8ajHkuXGdrHmFUTUUXhDwVX2R5bY4JNZEwbUiMhV+MA== 86 | 87 | map-obj@^4.0.0: 88 | version "4.2.1" 89 | resolved "https://registry.npmjs.org/map-obj/-/map-obj-4.2.1.tgz#e4ea399dbc979ae735c83c863dd31bdf364277b7" 90 | integrity sha512-+WA2/1sPmDj1dlvvJmB5G6JKfY9dpn7EVBUL06+y6PoljPkh+6V1QihwxNkbcGxCRjt2b0F9K0taiCuo7MbdFQ== 91 | 92 | miniprogram-api-typings@^3.3.0: 93 | version "3.3.1" 94 | resolved "https://registry.npmjs.org/miniprogram-api-typings/-/miniprogram-api-typings-3.3.1.tgz#1cc58437873fe01c1b4f382aa7630bd73d848c42" 95 | integrity sha512-3MTHaLgcuaLlMiEIVn3OdzJjLKgZfkpV/KrwxUYIL/+4b4BM6TAFYcwsXmQH7edOG9AUwU7pkQESpzE0ZjpPUQ== 96 | 97 | protobufjs@^6.10.2: 98 | version "6.10.2" 99 | resolved "https://registry.npmjs.org/protobufjs/-/protobufjs-6.10.2.tgz#b9cb6bd8ec8f87514592ba3fdfd28e93f33a469b" 100 | integrity sha512-27yj+04uF6ya9l+qfpH187aqEzfCF4+Uit0I9ZBQVqK09hk/SQzKa2MUqUpXaVa7LOFRg1TSSr3lVxGOk6c0SQ== 101 | dependencies: 102 | "@protobufjs/aspromise" "^1.1.2" 103 | "@protobufjs/base64" "^1.1.2" 104 | "@protobufjs/codegen" "^2.0.4" 105 | "@protobufjs/eventemitter" "^1.1.0" 106 | "@protobufjs/fetch" "^1.1.0" 107 | "@protobufjs/float" "^1.0.2" 108 | "@protobufjs/inquire" "^1.1.0" 109 | "@protobufjs/path" "^1.1.2" 110 | "@protobufjs/pool" "^1.1.0" 111 | "@protobufjs/utf8" "^1.1.0" 112 | "@types/long" "^4.0.1" 113 | "@types/node" "^13.7.0" 114 | long "^4.0.0" 115 | 116 | quick-lru@^4.0.1: 117 | version "4.0.1" 118 | resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz#5b8878f113a58217848c6482026c73e1ba57727f" 119 | integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== 120 | 121 | typescript@^4.2.3: 122 | version "4.2.4" 123 | resolved "https://registry.npmjs.org/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" 124 | integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== 125 | -------------------------------------------------------------------------------- /microsvcs/auth/api/gen/v1/auth.pb.gw.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. 2 | // source: auth.proto 3 | 4 | /* 5 | Package authpb is a reverse proxy. 6 | 7 | It translates gRPC into RESTful JSON APIs. 8 | */ 9 | package authpb 10 | 11 | import ( 12 | "context" 13 | "io" 14 | "net/http" 15 | 16 | "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" 17 | "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" 18 | "google.golang.org/grpc" 19 | "google.golang.org/grpc/codes" 20 | "google.golang.org/grpc/grpclog" 21 | "google.golang.org/grpc/metadata" 22 | "google.golang.org/grpc/status" 23 | "google.golang.org/protobuf/proto" 24 | ) 25 | 26 | // Suppress "imported and not used" errors 27 | var _ codes.Code 28 | var _ io.Reader 29 | var _ status.Status 30 | var _ = runtime.String 31 | var _ = utilities.NewDoubleArray 32 | var _ = metadata.Join 33 | 34 | func request_AuthService_Login_0(ctx context.Context, marshaler runtime.Marshaler, client AuthServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { 35 | var protoReq LoginRequest 36 | var metadata runtime.ServerMetadata 37 | 38 | newReader, berr := utilities.IOReaderFactory(req.Body) 39 | if berr != nil { 40 | return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) 41 | } 42 | if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { 43 | return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) 44 | } 45 | 46 | msg, err := client.Login(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) 47 | return msg, metadata, err 48 | 49 | } 50 | 51 | func local_request_AuthService_Login_0(ctx context.Context, marshaler runtime.Marshaler, server AuthServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { 52 | var protoReq LoginRequest 53 | var metadata runtime.ServerMetadata 54 | 55 | newReader, berr := utilities.IOReaderFactory(req.Body) 56 | if berr != nil { 57 | return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) 58 | } 59 | if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { 60 | return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) 61 | } 62 | 63 | msg, err := server.Login(ctx, &protoReq) 64 | return msg, metadata, err 65 | 66 | } 67 | 68 | // RegisterAuthServiceHandlerServer registers the http handlers for service AuthService to "mux". 69 | // UnaryRPC :call AuthServiceServer directly. 70 | // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. 71 | // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterAuthServiceHandlerFromEndpoint instead. 72 | func RegisterAuthServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server AuthServiceServer) error { 73 | 74 | mux.Handle("POST", pattern_AuthService_Login_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { 75 | ctx, cancel := context.WithCancel(req.Context()) 76 | defer cancel() 77 | var stream runtime.ServerTransportStream 78 | ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) 79 | inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) 80 | rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/auth.v1.AuthService/Login") 81 | if err != nil { 82 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 83 | return 84 | } 85 | resp, md, err := local_request_AuthService_Login_0(rctx, inboundMarshaler, server, req, pathParams) 86 | md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) 87 | ctx = runtime.NewServerMetadataContext(ctx, md) 88 | if err != nil { 89 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 90 | return 91 | } 92 | 93 | forward_AuthService_Login_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) 94 | 95 | }) 96 | 97 | return nil 98 | } 99 | 100 | // RegisterAuthServiceHandlerFromEndpoint is same as RegisterAuthServiceHandler but 101 | // automatically dials to "endpoint" and closes the connection when "ctx" gets done. 102 | func RegisterAuthServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { 103 | conn, err := grpc.Dial(endpoint, opts...) 104 | if err != nil { 105 | return err 106 | } 107 | defer func() { 108 | if err != nil { 109 | if cerr := conn.Close(); cerr != nil { 110 | grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) 111 | } 112 | return 113 | } 114 | go func() { 115 | <-ctx.Done() 116 | if cerr := conn.Close(); cerr != nil { 117 | grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) 118 | } 119 | }() 120 | }() 121 | 122 | return RegisterAuthServiceHandler(ctx, mux, conn) 123 | } 124 | 125 | // RegisterAuthServiceHandler registers the http handlers for service AuthService to "mux". 126 | // The handlers forward requests to the grpc endpoint over "conn". 127 | func RegisterAuthServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { 128 | return RegisterAuthServiceHandlerClient(ctx, mux, NewAuthServiceClient(conn)) 129 | } 130 | 131 | // RegisterAuthServiceHandlerClient registers the http handlers for service AuthService 132 | // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "AuthServiceClient". 133 | // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "AuthServiceClient" 134 | // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in 135 | // "AuthServiceClient" to call the correct interceptors. 136 | func RegisterAuthServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client AuthServiceClient) error { 137 | 138 | mux.Handle("POST", pattern_AuthService_Login_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { 139 | ctx, cancel := context.WithCancel(req.Context()) 140 | defer cancel() 141 | inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) 142 | rctx, err := runtime.AnnotateContext(ctx, mux, req, "/auth.v1.AuthService/Login") 143 | if err != nil { 144 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 145 | return 146 | } 147 | resp, md, err := request_AuthService_Login_0(rctx, inboundMarshaler, client, req, pathParams) 148 | ctx = runtime.NewServerMetadataContext(ctx, md) 149 | if err != nil { 150 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 151 | return 152 | } 153 | 154 | forward_AuthService_Login_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) 155 | 156 | }) 157 | 158 | return nil 159 | } 160 | 161 | var ( 162 | pattern_AuthService_Login_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2}, []string{"v1", "auth", "login"}, "")) 163 | ) 164 | 165 | var ( 166 | forward_AuthService_Login_0 = runtime.ForwardResponseMessage 167 | ) 168 | -------------------------------------------------------------------------------- /microsvcs/todo/api/gen/v1/todo.pb.gw.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. 2 | // source: todo.proto 3 | 4 | /* 5 | Package todopb is a reverse proxy. 6 | 7 | It translates gRPC into RESTful JSON APIs. 8 | */ 9 | package todopb 10 | 11 | import ( 12 | "context" 13 | "io" 14 | "net/http" 15 | 16 | "github.com/grpc-ecosystem/grpc-gateway/v2/runtime" 17 | "github.com/grpc-ecosystem/grpc-gateway/v2/utilities" 18 | "google.golang.org/grpc" 19 | "google.golang.org/grpc/codes" 20 | "google.golang.org/grpc/grpclog" 21 | "google.golang.org/grpc/metadata" 22 | "google.golang.org/grpc/status" 23 | "google.golang.org/protobuf/proto" 24 | ) 25 | 26 | // Suppress "imported and not used" errors 27 | var _ codes.Code 28 | var _ io.Reader 29 | var _ status.Status 30 | var _ = runtime.String 31 | var _ = utilities.NewDoubleArray 32 | var _ = metadata.Join 33 | 34 | func request_TodoService_CreateTodo_0(ctx context.Context, marshaler runtime.Marshaler, client TodoServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { 35 | var protoReq CreateTodoRequest 36 | var metadata runtime.ServerMetadata 37 | 38 | newReader, berr := utilities.IOReaderFactory(req.Body) 39 | if berr != nil { 40 | return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) 41 | } 42 | if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { 43 | return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) 44 | } 45 | 46 | msg, err := client.CreateTodo(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) 47 | return msg, metadata, err 48 | 49 | } 50 | 51 | func local_request_TodoService_CreateTodo_0(ctx context.Context, marshaler runtime.Marshaler, server TodoServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { 52 | var protoReq CreateTodoRequest 53 | var metadata runtime.ServerMetadata 54 | 55 | newReader, berr := utilities.IOReaderFactory(req.Body) 56 | if berr != nil { 57 | return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) 58 | } 59 | if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { 60 | return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) 61 | } 62 | 63 | msg, err := server.CreateTodo(ctx, &protoReq) 64 | return msg, metadata, err 65 | 66 | } 67 | 68 | // RegisterTodoServiceHandlerServer registers the http handlers for service TodoService to "mux". 69 | // UnaryRPC :call TodoServiceServer directly. 70 | // StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. 71 | // Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterTodoServiceHandlerFromEndpoint instead. 72 | func RegisterTodoServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server TodoServiceServer) error { 73 | 74 | mux.Handle("POST", pattern_TodoService_CreateTodo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { 75 | ctx, cancel := context.WithCancel(req.Context()) 76 | defer cancel() 77 | var stream runtime.ServerTransportStream 78 | ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) 79 | inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) 80 | rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/todo.v1.TodoService/CreateTodo") 81 | if err != nil { 82 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 83 | return 84 | } 85 | resp, md, err := local_request_TodoService_CreateTodo_0(rctx, inboundMarshaler, server, req, pathParams) 86 | md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) 87 | ctx = runtime.NewServerMetadataContext(ctx, md) 88 | if err != nil { 89 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 90 | return 91 | } 92 | 93 | forward_TodoService_CreateTodo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) 94 | 95 | }) 96 | 97 | return nil 98 | } 99 | 100 | // RegisterTodoServiceHandlerFromEndpoint is same as RegisterTodoServiceHandler but 101 | // automatically dials to "endpoint" and closes the connection when "ctx" gets done. 102 | func RegisterTodoServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { 103 | conn, err := grpc.Dial(endpoint, opts...) 104 | if err != nil { 105 | return err 106 | } 107 | defer func() { 108 | if err != nil { 109 | if cerr := conn.Close(); cerr != nil { 110 | grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) 111 | } 112 | return 113 | } 114 | go func() { 115 | <-ctx.Done() 116 | if cerr := conn.Close(); cerr != nil { 117 | grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) 118 | } 119 | }() 120 | }() 121 | 122 | return RegisterTodoServiceHandler(ctx, mux, conn) 123 | } 124 | 125 | // RegisterTodoServiceHandler registers the http handlers for service TodoService to "mux". 126 | // The handlers forward requests to the grpc endpoint over "conn". 127 | func RegisterTodoServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { 128 | return RegisterTodoServiceHandlerClient(ctx, mux, NewTodoServiceClient(conn)) 129 | } 130 | 131 | // RegisterTodoServiceHandlerClient registers the http handlers for service TodoService 132 | // to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "TodoServiceClient". 133 | // Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "TodoServiceClient" 134 | // doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in 135 | // "TodoServiceClient" to call the correct interceptors. 136 | func RegisterTodoServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client TodoServiceClient) error { 137 | 138 | mux.Handle("POST", pattern_TodoService_CreateTodo_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { 139 | ctx, cancel := context.WithCancel(req.Context()) 140 | defer cancel() 141 | inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) 142 | rctx, err := runtime.AnnotateContext(ctx, mux, req, "/todo.v1.TodoService/CreateTodo") 143 | if err != nil { 144 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 145 | return 146 | } 147 | resp, md, err := request_TodoService_CreateTodo_0(rctx, inboundMarshaler, client, req, pathParams) 148 | ctx = runtime.NewServerMetadataContext(ctx, md) 149 | if err != nil { 150 | runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) 151 | return 152 | } 153 | 154 | forward_TodoService_CreateTodo_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) 155 | 156 | }) 157 | 158 | return nil 159 | } 160 | 161 | var ( 162 | pattern_TodoService_CreateTodo_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v1", "todo"}, "")) 163 | ) 164 | 165 | var ( 166 | forward_TodoService_CreateTodo_0 = runtime.ForwardResponseMessage 167 | ) 168 | -------------------------------------------------------------------------------- /microsvcs/todo/api/gen/v1/todo.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.26.0 4 | // protoc v3.15.7 5 | // source: todo.proto 6 | 7 | package todopb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type CreateTodoRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Title string `protobuf:"bytes,1,opt,name=title,proto3" json:"title,omitempty"` 29 | } 30 | 31 | func (x *CreateTodoRequest) Reset() { 32 | *x = CreateTodoRequest{} 33 | if protoimpl.UnsafeEnabled { 34 | mi := &file_todo_proto_msgTypes[0] 35 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 36 | ms.StoreMessageInfo(mi) 37 | } 38 | } 39 | 40 | func (x *CreateTodoRequest) String() string { 41 | return protoimpl.X.MessageStringOf(x) 42 | } 43 | 44 | func (*CreateTodoRequest) ProtoMessage() {} 45 | 46 | func (x *CreateTodoRequest) ProtoReflect() protoreflect.Message { 47 | mi := &file_todo_proto_msgTypes[0] 48 | if protoimpl.UnsafeEnabled && x != nil { 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | if ms.LoadMessageInfo() == nil { 51 | ms.StoreMessageInfo(mi) 52 | } 53 | return ms 54 | } 55 | return mi.MessageOf(x) 56 | } 57 | 58 | // Deprecated: Use CreateTodoRequest.ProtoReflect.Descriptor instead. 59 | func (*CreateTodoRequest) Descriptor() ([]byte, []int) { 60 | return file_todo_proto_rawDescGZIP(), []int{0} 61 | } 62 | 63 | func (x *CreateTodoRequest) GetTitle() string { 64 | if x != nil { 65 | return x.Title 66 | } 67 | return "" 68 | } 69 | 70 | type CreateTodoResponse struct { 71 | state protoimpl.MessageState 72 | sizeCache protoimpl.SizeCache 73 | unknownFields protoimpl.UnknownFields 74 | } 75 | 76 | func (x *CreateTodoResponse) Reset() { 77 | *x = CreateTodoResponse{} 78 | if protoimpl.UnsafeEnabled { 79 | mi := &file_todo_proto_msgTypes[1] 80 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 81 | ms.StoreMessageInfo(mi) 82 | } 83 | } 84 | 85 | func (x *CreateTodoResponse) String() string { 86 | return protoimpl.X.MessageStringOf(x) 87 | } 88 | 89 | func (*CreateTodoResponse) ProtoMessage() {} 90 | 91 | func (x *CreateTodoResponse) ProtoReflect() protoreflect.Message { 92 | mi := &file_todo_proto_msgTypes[1] 93 | if protoimpl.UnsafeEnabled && x != nil { 94 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 95 | if ms.LoadMessageInfo() == nil { 96 | ms.StoreMessageInfo(mi) 97 | } 98 | return ms 99 | } 100 | return mi.MessageOf(x) 101 | } 102 | 103 | // Deprecated: Use CreateTodoResponse.ProtoReflect.Descriptor instead. 104 | func (*CreateTodoResponse) Descriptor() ([]byte, []int) { 105 | return file_todo_proto_rawDescGZIP(), []int{1} 106 | } 107 | 108 | var File_todo_proto protoreflect.FileDescriptor 109 | 110 | var file_todo_proto_rawDesc = []byte{ 111 | 0x0a, 0x0a, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x74, 0x6f, 112 | 0x64, 0x6f, 0x2e, 0x76, 0x31, 0x22, 0x29, 0x0a, 0x11, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 113 | 0x6f, 0x64, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x74, 0x69, 114 | 0x74, 0x6c, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x74, 0x69, 0x74, 0x6c, 0x65, 115 | 0x22, 0x14, 0x0a, 0x12, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x64, 0x6f, 0x52, 0x65, 116 | 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x32, 0x54, 0x0a, 0x0b, 0x54, 0x6f, 0x64, 0x6f, 0x53, 0x65, 117 | 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x45, 0x0a, 0x0a, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x54, 118 | 0x6f, 0x64, 0x6f, 0x12, 0x1a, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 119 | 0x65, 0x61, 0x74, 0x65, 0x54, 0x6f, 0x64, 0x6f, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 120 | 0x1b, 0x2e, 0x74, 0x6f, 0x64, 0x6f, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 121 | 0x54, 0x6f, 0x64, 0x6f, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x42, 0x1f, 0x5a, 0x1d, 122 | 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x74, 0x6f, 0x64, 0x6f, 0x2f, 0x61, 0x70, 0x69, 0x2f, 123 | 0x67, 0x65, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x74, 0x6f, 0x64, 0x6f, 0x70, 0x62, 0x62, 0x06, 0x70, 124 | 0x72, 0x6f, 0x74, 0x6f, 0x33, 125 | } 126 | 127 | var ( 128 | file_todo_proto_rawDescOnce sync.Once 129 | file_todo_proto_rawDescData = file_todo_proto_rawDesc 130 | ) 131 | 132 | func file_todo_proto_rawDescGZIP() []byte { 133 | file_todo_proto_rawDescOnce.Do(func() { 134 | file_todo_proto_rawDescData = protoimpl.X.CompressGZIP(file_todo_proto_rawDescData) 135 | }) 136 | return file_todo_proto_rawDescData 137 | } 138 | 139 | var file_todo_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 140 | var file_todo_proto_goTypes = []interface{}{ 141 | (*CreateTodoRequest)(nil), // 0: todo.v1.CreateTodoRequest 142 | (*CreateTodoResponse)(nil), // 1: todo.v1.CreateTodoResponse 143 | } 144 | var file_todo_proto_depIdxs = []int32{ 145 | 0, // 0: todo.v1.TodoService.CreateTodo:input_type -> todo.v1.CreateTodoRequest 146 | 1, // 1: todo.v1.TodoService.CreateTodo:output_type -> todo.v1.CreateTodoResponse 147 | 1, // [1:2] is the sub-list for method output_type 148 | 0, // [0:1] is the sub-list for method input_type 149 | 0, // [0:0] is the sub-list for extension type_name 150 | 0, // [0:0] is the sub-list for extension extendee 151 | 0, // [0:0] is the sub-list for field type_name 152 | } 153 | 154 | func init() { file_todo_proto_init() } 155 | func file_todo_proto_init() { 156 | if File_todo_proto != nil { 157 | return 158 | } 159 | if !protoimpl.UnsafeEnabled { 160 | file_todo_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 161 | switch v := v.(*CreateTodoRequest); i { 162 | case 0: 163 | return &v.state 164 | case 1: 165 | return &v.sizeCache 166 | case 2: 167 | return &v.unknownFields 168 | default: 169 | return nil 170 | } 171 | } 172 | file_todo_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 173 | switch v := v.(*CreateTodoResponse); i { 174 | case 0: 175 | return &v.state 176 | case 1: 177 | return &v.sizeCache 178 | case 2: 179 | return &v.unknownFields 180 | default: 181 | return nil 182 | } 183 | } 184 | } 185 | type x struct{} 186 | out := protoimpl.TypeBuilder{ 187 | File: protoimpl.DescBuilder{ 188 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 189 | RawDescriptor: file_todo_proto_rawDesc, 190 | NumEnums: 0, 191 | NumMessages: 2, 192 | NumExtensions: 0, 193 | NumServices: 1, 194 | }, 195 | GoTypes: file_todo_proto_goTypes, 196 | DependencyIndexes: file_todo_proto_depIdxs, 197 | MessageInfos: file_todo_proto_msgTypes, 198 | }.Build() 199 | File_todo_proto = out.File 200 | file_todo_proto_rawDesc = nil 201 | file_todo_proto_goTypes = nil 202 | file_todo_proto_depIdxs = nil 203 | } 204 | -------------------------------------------------------------------------------- /microsvcs/auth/api/gen/v1/auth.pb.go: -------------------------------------------------------------------------------- 1 | // Code generated by protoc-gen-go. DO NOT EDIT. 2 | // versions: 3 | // protoc-gen-go v1.26.0 4 | // protoc v3.15.7 5 | // source: auth.proto 6 | 7 | package authpb 8 | 9 | import ( 10 | protoreflect "google.golang.org/protobuf/reflect/protoreflect" 11 | protoimpl "google.golang.org/protobuf/runtime/protoimpl" 12 | reflect "reflect" 13 | sync "sync" 14 | ) 15 | 16 | const ( 17 | // Verify that this generated code is sufficiently up-to-date. 18 | _ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion) 19 | // Verify that runtime/protoimpl is sufficiently up-to-date. 20 | _ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20) 21 | ) 22 | 23 | type LoginRequest struct { 24 | state protoimpl.MessageState 25 | sizeCache protoimpl.SizeCache 26 | unknownFields protoimpl.UnknownFields 27 | 28 | Code string `protobuf:"bytes,1,opt,name=code,proto3" json:"code,omitempty"` 29 | } 30 | 31 | func (x *LoginRequest) Reset() { 32 | *x = LoginRequest{} 33 | if protoimpl.UnsafeEnabled { 34 | mi := &file_auth_proto_msgTypes[0] 35 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 36 | ms.StoreMessageInfo(mi) 37 | } 38 | } 39 | 40 | func (x *LoginRequest) String() string { 41 | return protoimpl.X.MessageStringOf(x) 42 | } 43 | 44 | func (*LoginRequest) ProtoMessage() {} 45 | 46 | func (x *LoginRequest) ProtoReflect() protoreflect.Message { 47 | mi := &file_auth_proto_msgTypes[0] 48 | if protoimpl.UnsafeEnabled && x != nil { 49 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 50 | if ms.LoadMessageInfo() == nil { 51 | ms.StoreMessageInfo(mi) 52 | } 53 | return ms 54 | } 55 | return mi.MessageOf(x) 56 | } 57 | 58 | // Deprecated: Use LoginRequest.ProtoReflect.Descriptor instead. 59 | func (*LoginRequest) Descriptor() ([]byte, []int) { 60 | return file_auth_proto_rawDescGZIP(), []int{0} 61 | } 62 | 63 | func (x *LoginRequest) GetCode() string { 64 | if x != nil { 65 | return x.Code 66 | } 67 | return "" 68 | } 69 | 70 | type LoginResponse struct { 71 | state protoimpl.MessageState 72 | sizeCache protoimpl.SizeCache 73 | unknownFields protoimpl.UnknownFields 74 | 75 | AccessToken string `protobuf:"bytes,1,opt,name=access_token,json=accessToken,proto3" json:"access_token,omitempty"` 76 | ExpiresIn int32 `protobuf:"varint,2,opt,name=expires_in,json=expiresIn,proto3" json:"expires_in,omitempty"` // 按 oauth2 约定走 77 | } 78 | 79 | func (x *LoginResponse) Reset() { 80 | *x = LoginResponse{} 81 | if protoimpl.UnsafeEnabled { 82 | mi := &file_auth_proto_msgTypes[1] 83 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 84 | ms.StoreMessageInfo(mi) 85 | } 86 | } 87 | 88 | func (x *LoginResponse) String() string { 89 | return protoimpl.X.MessageStringOf(x) 90 | } 91 | 92 | func (*LoginResponse) ProtoMessage() {} 93 | 94 | func (x *LoginResponse) ProtoReflect() protoreflect.Message { 95 | mi := &file_auth_proto_msgTypes[1] 96 | if protoimpl.UnsafeEnabled && x != nil { 97 | ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) 98 | if ms.LoadMessageInfo() == nil { 99 | ms.StoreMessageInfo(mi) 100 | } 101 | return ms 102 | } 103 | return mi.MessageOf(x) 104 | } 105 | 106 | // Deprecated: Use LoginResponse.ProtoReflect.Descriptor instead. 107 | func (*LoginResponse) Descriptor() ([]byte, []int) { 108 | return file_auth_proto_rawDescGZIP(), []int{1} 109 | } 110 | 111 | func (x *LoginResponse) GetAccessToken() string { 112 | if x != nil { 113 | return x.AccessToken 114 | } 115 | return "" 116 | } 117 | 118 | func (x *LoginResponse) GetExpiresIn() int32 { 119 | if x != nil { 120 | return x.ExpiresIn 121 | } 122 | return 0 123 | } 124 | 125 | var File_auth_proto protoreflect.FileDescriptor 126 | 127 | var file_auth_proto_rawDesc = []byte{ 128 | 0x0a, 0x0a, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x12, 0x07, 0x61, 0x75, 129 | 0x74, 0x68, 0x2e, 0x76, 0x31, 0x22, 0x22, 0x0a, 0x0c, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 130 | 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 131 | 0x01, 0x28, 0x09, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x22, 0x51, 0x0a, 0x0d, 0x4c, 0x6f, 0x67, 132 | 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 133 | 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 134 | 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x12, 0x1d, 0x0a, 135 | 0x0a, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x5f, 0x69, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 136 | 0x05, 0x52, 0x09, 0x65, 0x78, 0x70, 0x69, 0x72, 0x65, 0x73, 0x49, 0x6e, 0x32, 0x45, 0x0a, 0x0b, 137 | 0x41, 0x75, 0x74, 0x68, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x36, 0x0a, 0x05, 0x4c, 138 | 0x6f, 0x67, 0x69, 0x6e, 0x12, 0x15, 0x2e, 0x61, 0x75, 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 139 | 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, 0x61, 0x75, 140 | 0x74, 0x68, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x69, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 141 | 0x6e, 0x73, 0x65, 0x42, 0x1f, 0x5a, 0x1d, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2f, 0x61, 0x75, 142 | 0x74, 0x68, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x76, 0x31, 0x3b, 0x61, 0x75, 143 | 0x74, 0x68, 0x70, 0x62, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, 144 | } 145 | 146 | var ( 147 | file_auth_proto_rawDescOnce sync.Once 148 | file_auth_proto_rawDescData = file_auth_proto_rawDesc 149 | ) 150 | 151 | func file_auth_proto_rawDescGZIP() []byte { 152 | file_auth_proto_rawDescOnce.Do(func() { 153 | file_auth_proto_rawDescData = protoimpl.X.CompressGZIP(file_auth_proto_rawDescData) 154 | }) 155 | return file_auth_proto_rawDescData 156 | } 157 | 158 | var file_auth_proto_msgTypes = make([]protoimpl.MessageInfo, 2) 159 | var file_auth_proto_goTypes = []interface{}{ 160 | (*LoginRequest)(nil), // 0: auth.v1.LoginRequest 161 | (*LoginResponse)(nil), // 1: auth.v1.LoginResponse 162 | } 163 | var file_auth_proto_depIdxs = []int32{ 164 | 0, // 0: auth.v1.AuthService.Login:input_type -> auth.v1.LoginRequest 165 | 1, // 1: auth.v1.AuthService.Login:output_type -> auth.v1.LoginResponse 166 | 1, // [1:2] is the sub-list for method output_type 167 | 0, // [0:1] is the sub-list for method input_type 168 | 0, // [0:0] is the sub-list for extension type_name 169 | 0, // [0:0] is the sub-list for extension extendee 170 | 0, // [0:0] is the sub-list for field type_name 171 | } 172 | 173 | func init() { file_auth_proto_init() } 174 | func file_auth_proto_init() { 175 | if File_auth_proto != nil { 176 | return 177 | } 178 | if !protoimpl.UnsafeEnabled { 179 | file_auth_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} { 180 | switch v := v.(*LoginRequest); i { 181 | case 0: 182 | return &v.state 183 | case 1: 184 | return &v.sizeCache 185 | case 2: 186 | return &v.unknownFields 187 | default: 188 | return nil 189 | } 190 | } 191 | file_auth_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} { 192 | switch v := v.(*LoginResponse); i { 193 | case 0: 194 | return &v.state 195 | case 1: 196 | return &v.sizeCache 197 | case 2: 198 | return &v.unknownFields 199 | default: 200 | return nil 201 | } 202 | } 203 | } 204 | type x struct{} 205 | out := protoimpl.TypeBuilder{ 206 | File: protoimpl.DescBuilder{ 207 | GoPackagePath: reflect.TypeOf(x{}).PkgPath(), 208 | RawDescriptor: file_auth_proto_rawDesc, 209 | NumEnums: 0, 210 | NumMessages: 2, 211 | NumExtensions: 0, 212 | NumServices: 1, 213 | }, 214 | GoTypes: file_auth_proto_goTypes, 215 | DependencyIndexes: file_auth_proto_depIdxs, 216 | MessageInfos: file_auth_proto_msgTypes, 217 | }.Build() 218 | File_auth_proto = out.File 219 | file_auth_proto_rawDesc = nil 220 | file_auth_proto_goTypes = nil 221 | file_auth_proto_depIdxs = nil 222 | } 223 | -------------------------------------------------------------------------------- /client/miniprogram/service/proto_gen/todo/todo_pb.js: -------------------------------------------------------------------------------- 1 | import * as $protobuf from "protobufjs"; 2 | 3 | // Common aliases 4 | const $util = $protobuf.util; 5 | 6 | // Exported root namespace 7 | const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); 8 | 9 | export const todo = $root.todo = (() => { 10 | 11 | /** 12 | * Namespace todo. 13 | * @exports todo 14 | * @namespace 15 | */ 16 | const todo = {}; 17 | 18 | todo.v1 = (function() { 19 | 20 | /** 21 | * Namespace v1. 22 | * @memberof todo 23 | * @namespace 24 | */ 25 | const v1 = {}; 26 | 27 | v1.CreateTodoRequest = (function() { 28 | 29 | /** 30 | * Properties of a CreateTodoRequest. 31 | * @memberof todo.v1 32 | * @interface ICreateTodoRequest 33 | * @property {string|null} [title] CreateTodoRequest title 34 | */ 35 | 36 | /** 37 | * Constructs a new CreateTodoRequest. 38 | * @memberof todo.v1 39 | * @classdesc Represents a CreateTodoRequest. 40 | * @implements ICreateTodoRequest 41 | * @constructor 42 | * @param {todo.v1.ICreateTodoRequest=} [properties] Properties to set 43 | */ 44 | function CreateTodoRequest(properties) { 45 | if (properties) 46 | for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) 47 | if (properties[keys[i]] != null) 48 | this[keys[i]] = properties[keys[i]]; 49 | } 50 | 51 | /** 52 | * CreateTodoRequest title. 53 | * @member {string} title 54 | * @memberof todo.v1.CreateTodoRequest 55 | * @instance 56 | */ 57 | CreateTodoRequest.prototype.title = ""; 58 | 59 | /** 60 | * Creates a CreateTodoRequest message from a plain object. Also converts values to their respective internal types. 61 | * @function fromObject 62 | * @memberof todo.v1.CreateTodoRequest 63 | * @static 64 | * @param {Object.} object Plain object 65 | * @returns {todo.v1.CreateTodoRequest} CreateTodoRequest 66 | */ 67 | CreateTodoRequest.fromObject = function fromObject(object) { 68 | if (object instanceof $root.todo.v1.CreateTodoRequest) 69 | return object; 70 | let message = new $root.todo.v1.CreateTodoRequest(); 71 | if (object.title != null) 72 | message.title = String(object.title); 73 | return message; 74 | }; 75 | 76 | /** 77 | * Creates a plain object from a CreateTodoRequest message. Also converts values to other types if specified. 78 | * @function toObject 79 | * @memberof todo.v1.CreateTodoRequest 80 | * @static 81 | * @param {todo.v1.CreateTodoRequest} message CreateTodoRequest 82 | * @param {$protobuf.IConversionOptions} [options] Conversion options 83 | * @returns {Object.} Plain object 84 | */ 85 | CreateTodoRequest.toObject = function toObject(message, options) { 86 | if (!options) 87 | options = {}; 88 | let object = {}; 89 | if (options.defaults) 90 | object.title = ""; 91 | if (message.title != null && message.hasOwnProperty("title")) 92 | object.title = message.title; 93 | return object; 94 | }; 95 | 96 | /** 97 | * Converts this CreateTodoRequest to JSON. 98 | * @function toJSON 99 | * @memberof todo.v1.CreateTodoRequest 100 | * @instance 101 | * @returns {Object.} JSON object 102 | */ 103 | CreateTodoRequest.prototype.toJSON = function toJSON() { 104 | return this.constructor.toObject(this, $protobuf.util.toJSONOptions); 105 | }; 106 | 107 | return CreateTodoRequest; 108 | })(); 109 | 110 | v1.CreateTodoResponse = (function() { 111 | 112 | /** 113 | * Properties of a CreateTodoResponse. 114 | * @memberof todo.v1 115 | * @interface ICreateTodoResponse 116 | */ 117 | 118 | /** 119 | * Constructs a new CreateTodoResponse. 120 | * @memberof todo.v1 121 | * @classdesc Represents a CreateTodoResponse. 122 | * @implements ICreateTodoResponse 123 | * @constructor 124 | * @param {todo.v1.ICreateTodoResponse=} [properties] Properties to set 125 | */ 126 | function CreateTodoResponse(properties) { 127 | if (properties) 128 | for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) 129 | if (properties[keys[i]] != null) 130 | this[keys[i]] = properties[keys[i]]; 131 | } 132 | 133 | /** 134 | * Creates a CreateTodoResponse message from a plain object. Also converts values to their respective internal types. 135 | * @function fromObject 136 | * @memberof todo.v1.CreateTodoResponse 137 | * @static 138 | * @param {Object.} object Plain object 139 | * @returns {todo.v1.CreateTodoResponse} CreateTodoResponse 140 | */ 141 | CreateTodoResponse.fromObject = function fromObject(object) { 142 | if (object instanceof $root.todo.v1.CreateTodoResponse) 143 | return object; 144 | return new $root.todo.v1.CreateTodoResponse(); 145 | }; 146 | 147 | /** 148 | * Creates a plain object from a CreateTodoResponse message. Also converts values to other types if specified. 149 | * @function toObject 150 | * @memberof todo.v1.CreateTodoResponse 151 | * @static 152 | * @param {todo.v1.CreateTodoResponse} message CreateTodoResponse 153 | * @param {$protobuf.IConversionOptions} [options] Conversion options 154 | * @returns {Object.} Plain object 155 | */ 156 | CreateTodoResponse.toObject = function toObject() { 157 | return {}; 158 | }; 159 | 160 | /** 161 | * Converts this CreateTodoResponse to JSON. 162 | * @function toJSON 163 | * @memberof todo.v1.CreateTodoResponse 164 | * @instance 165 | * @returns {Object.} JSON object 166 | */ 167 | CreateTodoResponse.prototype.toJSON = function toJSON() { 168 | return this.constructor.toObject(this, $protobuf.util.toJSONOptions); 169 | }; 170 | 171 | return CreateTodoResponse; 172 | })(); 173 | 174 | v1.TodoService = (function() { 175 | 176 | /** 177 | * Constructs a new TodoService service. 178 | * @memberof todo.v1 179 | * @classdesc Represents a TodoService 180 | * @extends $protobuf.rpc.Service 181 | * @constructor 182 | * @param {$protobuf.RPCImpl} rpcImpl RPC implementation 183 | * @param {boolean} [requestDelimited=false] Whether requests are length-delimited 184 | * @param {boolean} [responseDelimited=false] Whether responses are length-delimited 185 | */ 186 | function TodoService(rpcImpl, requestDelimited, responseDelimited) { 187 | $protobuf.rpc.Service.call(this, rpcImpl, requestDelimited, responseDelimited); 188 | } 189 | 190 | (TodoService.prototype = Object.create($protobuf.rpc.Service.prototype)).constructor = TodoService; 191 | 192 | /** 193 | * Callback as used by {@link todo.v1.TodoService#createTodo}. 194 | * @memberof todo.v1.TodoService 195 | * @typedef CreateTodoCallback 196 | * @type {function} 197 | * @param {Error|null} error Error, if any 198 | * @param {todo.v1.CreateTodoResponse} [response] CreateTodoResponse 199 | */ 200 | 201 | /** 202 | * Calls CreateTodo. 203 | * @function createTodo 204 | * @memberof todo.v1.TodoService 205 | * @instance 206 | * @param {todo.v1.ICreateTodoRequest} request CreateTodoRequest message or plain object 207 | * @param {todo.v1.TodoService.CreateTodoCallback} callback Node-style callback called with the error, if any, and CreateTodoResponse 208 | * @returns {undefined} 209 | * @variation 1 210 | */ 211 | Object.defineProperty(TodoService.prototype.createTodo = function createTodo(request, callback) { 212 | return this.rpcCall(createTodo, $root.todo.v1.CreateTodoRequest, $root.todo.v1.CreateTodoResponse, request, callback); 213 | }, "name", { value: "CreateTodo" }); 214 | 215 | /** 216 | * Calls CreateTodo. 217 | * @function createTodo 218 | * @memberof todo.v1.TodoService 219 | * @instance 220 | * @param {todo.v1.ICreateTodoRequest} request CreateTodoRequest message or plain object 221 | * @returns {Promise} Promise 222 | * @variation 2 223 | */ 224 | 225 | return TodoService; 226 | })(); 227 | 228 | return v1; 229 | })(); 230 | 231 | return todo; 232 | })(); -------------------------------------------------------------------------------- /client/miniprogram/service/proto_gen/auth/auth_pb.js: -------------------------------------------------------------------------------- 1 | import * as $protobuf from "protobufjs"; 2 | 3 | // Common aliases 4 | const $util = $protobuf.util; 5 | 6 | // Exported root namespace 7 | const $root = $protobuf.roots["default"] || ($protobuf.roots["default"] = {}); 8 | 9 | export const auth = $root.auth = (() => { 10 | 11 | /** 12 | * Namespace auth. 13 | * @exports auth 14 | * @namespace 15 | */ 16 | const auth = {}; 17 | 18 | auth.v1 = (function() { 19 | 20 | /** 21 | * Namespace v1. 22 | * @memberof auth 23 | * @namespace 24 | */ 25 | const v1 = {}; 26 | 27 | v1.LoginRequest = (function() { 28 | 29 | /** 30 | * Properties of a LoginRequest. 31 | * @memberof auth.v1 32 | * @interface ILoginRequest 33 | * @property {string|null} [code] LoginRequest code 34 | */ 35 | 36 | /** 37 | * Constructs a new LoginRequest. 38 | * @memberof auth.v1 39 | * @classdesc Represents a LoginRequest. 40 | * @implements ILoginRequest 41 | * @constructor 42 | * @param {auth.v1.ILoginRequest=} [properties] Properties to set 43 | */ 44 | function LoginRequest(properties) { 45 | if (properties) 46 | for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) 47 | if (properties[keys[i]] != null) 48 | this[keys[i]] = properties[keys[i]]; 49 | } 50 | 51 | /** 52 | * LoginRequest code. 53 | * @member {string} code 54 | * @memberof auth.v1.LoginRequest 55 | * @instance 56 | */ 57 | LoginRequest.prototype.code = ""; 58 | 59 | /** 60 | * Creates a LoginRequest message from a plain object. Also converts values to their respective internal types. 61 | * @function fromObject 62 | * @memberof auth.v1.LoginRequest 63 | * @static 64 | * @param {Object.} object Plain object 65 | * @returns {auth.v1.LoginRequest} LoginRequest 66 | */ 67 | LoginRequest.fromObject = function fromObject(object) { 68 | if (object instanceof $root.auth.v1.LoginRequest) 69 | return object; 70 | let message = new $root.auth.v1.LoginRequest(); 71 | if (object.code != null) 72 | message.code = String(object.code); 73 | return message; 74 | }; 75 | 76 | /** 77 | * Creates a plain object from a LoginRequest message. Also converts values to other types if specified. 78 | * @function toObject 79 | * @memberof auth.v1.LoginRequest 80 | * @static 81 | * @param {auth.v1.LoginRequest} message LoginRequest 82 | * @param {$protobuf.IConversionOptions} [options] Conversion options 83 | * @returns {Object.} Plain object 84 | */ 85 | LoginRequest.toObject = function toObject(message, options) { 86 | if (!options) 87 | options = {}; 88 | let object = {}; 89 | if (options.defaults) 90 | object.code = ""; 91 | if (message.code != null && message.hasOwnProperty("code")) 92 | object.code = message.code; 93 | return object; 94 | }; 95 | 96 | /** 97 | * Converts this LoginRequest to JSON. 98 | * @function toJSON 99 | * @memberof auth.v1.LoginRequest 100 | * @instance 101 | * @returns {Object.} JSON object 102 | */ 103 | LoginRequest.prototype.toJSON = function toJSON() { 104 | return this.constructor.toObject(this, $protobuf.util.toJSONOptions); 105 | }; 106 | 107 | return LoginRequest; 108 | })(); 109 | 110 | v1.LoginResponse = (function() { 111 | 112 | /** 113 | * Properties of a LoginResponse. 114 | * @memberof auth.v1 115 | * @interface ILoginResponse 116 | * @property {string|null} [accessToken] LoginResponse accessToken 117 | * @property {number|null} [expiresIn] LoginResponse expiresIn 118 | */ 119 | 120 | /** 121 | * Constructs a new LoginResponse. 122 | * @memberof auth.v1 123 | * @classdesc Represents a LoginResponse. 124 | * @implements ILoginResponse 125 | * @constructor 126 | * @param {auth.v1.ILoginResponse=} [properties] Properties to set 127 | */ 128 | function LoginResponse(properties) { 129 | if (properties) 130 | for (let keys = Object.keys(properties), i = 0; i < keys.length; ++i) 131 | if (properties[keys[i]] != null) 132 | this[keys[i]] = properties[keys[i]]; 133 | } 134 | 135 | /** 136 | * LoginResponse accessToken. 137 | * @member {string} accessToken 138 | * @memberof auth.v1.LoginResponse 139 | * @instance 140 | */ 141 | LoginResponse.prototype.accessToken = ""; 142 | 143 | /** 144 | * LoginResponse expiresIn. 145 | * @member {number} expiresIn 146 | * @memberof auth.v1.LoginResponse 147 | * @instance 148 | */ 149 | LoginResponse.prototype.expiresIn = 0; 150 | 151 | /** 152 | * Creates a LoginResponse message from a plain object. Also converts values to their respective internal types. 153 | * @function fromObject 154 | * @memberof auth.v1.LoginResponse 155 | * @static 156 | * @param {Object.} object Plain object 157 | * @returns {auth.v1.LoginResponse} LoginResponse 158 | */ 159 | LoginResponse.fromObject = function fromObject(object) { 160 | if (object instanceof $root.auth.v1.LoginResponse) 161 | return object; 162 | let message = new $root.auth.v1.LoginResponse(); 163 | if (object.accessToken != null) 164 | message.accessToken = String(object.accessToken); 165 | if (object.expiresIn != null) 166 | message.expiresIn = object.expiresIn | 0; 167 | return message; 168 | }; 169 | 170 | /** 171 | * Creates a plain object from a LoginResponse message. Also converts values to other types if specified. 172 | * @function toObject 173 | * @memberof auth.v1.LoginResponse 174 | * @static 175 | * @param {auth.v1.LoginResponse} message LoginResponse 176 | * @param {$protobuf.IConversionOptions} [options] Conversion options 177 | * @returns {Object.} Plain object 178 | */ 179 | LoginResponse.toObject = function toObject(message, options) { 180 | if (!options) 181 | options = {}; 182 | let object = {}; 183 | if (options.defaults) { 184 | object.accessToken = ""; 185 | object.expiresIn = 0; 186 | } 187 | if (message.accessToken != null && message.hasOwnProperty("accessToken")) 188 | object.accessToken = message.accessToken; 189 | if (message.expiresIn != null && message.hasOwnProperty("expiresIn")) 190 | object.expiresIn = message.expiresIn; 191 | return object; 192 | }; 193 | 194 | /** 195 | * Converts this LoginResponse to JSON. 196 | * @function toJSON 197 | * @memberof auth.v1.LoginResponse 198 | * @instance 199 | * @returns {Object.} JSON object 200 | */ 201 | LoginResponse.prototype.toJSON = function toJSON() { 202 | return this.constructor.toObject(this, $protobuf.util.toJSONOptions); 203 | }; 204 | 205 | return LoginResponse; 206 | })(); 207 | 208 | v1.AuthService = (function() { 209 | 210 | /** 211 | * Constructs a new AuthService service. 212 | * @memberof auth.v1 213 | * @classdesc Represents an AuthService 214 | * @extends $protobuf.rpc.Service 215 | * @constructor 216 | * @param {$protobuf.RPCImpl} rpcImpl RPC implementation 217 | * @param {boolean} [requestDelimited=false] Whether requests are length-delimited 218 | * @param {boolean} [responseDelimited=false] Whether responses are length-delimited 219 | */ 220 | function AuthService(rpcImpl, requestDelimited, responseDelimited) { 221 | $protobuf.rpc.Service.call(this, rpcImpl, requestDelimited, responseDelimited); 222 | } 223 | 224 | (AuthService.prototype = Object.create($protobuf.rpc.Service.prototype)).constructor = AuthService; 225 | 226 | /** 227 | * Callback as used by {@link auth.v1.AuthService#login}. 228 | * @memberof auth.v1.AuthService 229 | * @typedef LoginCallback 230 | * @type {function} 231 | * @param {Error|null} error Error, if any 232 | * @param {auth.v1.LoginResponse} [response] LoginResponse 233 | */ 234 | 235 | /** 236 | * Calls Login. 237 | * @function login 238 | * @memberof auth.v1.AuthService 239 | * @instance 240 | * @param {auth.v1.ILoginRequest} request LoginRequest message or plain object 241 | * @param {auth.v1.AuthService.LoginCallback} callback Node-style callback called with the error, if any, and LoginResponse 242 | * @returns {undefined} 243 | * @variation 1 244 | */ 245 | Object.defineProperty(AuthService.prototype.login = function login(request, callback) { 246 | return this.rpcCall(login, $root.auth.v1.LoginRequest, $root.auth.v1.LoginResponse, request, callback); 247 | }, "name", { value: "Login" }); 248 | 249 | /** 250 | * Calls Login. 251 | * @function login 252 | * @memberof auth.v1.AuthService 253 | * @instance 254 | * @param {auth.v1.ILoginRequest} request LoginRequest message or plain object 255 | * @returns {Promise} Promise 256 | * @variation 2 257 | */ 258 | 259 | return AuthService; 260 | })(); 261 | 262 | return v1; 263 | })(); 264 | 265 | return auth; 266 | })(); -------------------------------------------------------------------------------- /architecture_introduction_diagram.svg: -------------------------------------------------------------------------------- 1 | --------------------------------------------------------------------------------