Commit 1b1ad555363e65b30856648c32b5185c52237236
1 parent
66502d8d
tls测试代码
Showing
10 changed files
with
122 additions
and
45 deletions
Show diff stats
actions/accountaction.go
... | ... | @@ -3,6 +3,7 @@ package actions |
3 | 3 | import ( |
4 | 4 | "context" |
5 | 5 | "fmt" |
6 | + "pro2d/components/jwt" | |
6 | 7 | "pro2d/conf" |
7 | 8 | "pro2d/models" |
8 | 9 | "pro2d/protos/pb" |
... | ... | @@ -52,7 +53,7 @@ func (s *LoginServer) CreateTokenHandler(ctx context.Context, in *pb.Account) (* |
52 | 53 | return &pb.CreateTokenRsp{ |
53 | 54 | Code: 0, |
54 | 55 | Uid: m.Uid, |
55 | - Token: utils.CreateToken(m.Account), | |
56 | + Token: jwt.CreateToken(m.Account.Uid), | |
56 | 57 | GameService: gameInfo, |
57 | 58 | }, nil |
58 | 59 | } | ... | ... |
actions/roleaction.go
... | ... | @@ -3,7 +3,6 @@ package actions |
3 | 3 | import ( |
4 | 4 | "context" |
5 | 5 | "errors" |
6 | - "fmt" | |
7 | 6 | "google.golang.org/grpc/metadata" |
8 | 7 | "google.golang.org/protobuf/types/known/emptypb" |
9 | 8 | "pro2d/conf" |
... | ... | @@ -26,16 +25,12 @@ func (s *GameServer) HeartBeatHandler(ctx context.Context, empty *emptypb.Empty) |
26 | 25 | } |
27 | 26 | |
28 | 27 | func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.LoginReq) (*pb.RoleRsp, error) { |
29 | - account := utils.CheckAuth(ctx) | |
30 | - if account == nil { | |
31 | - return nil, fmt.Errorf("token error") | |
32 | - } | |
33 | - | |
34 | - ok, role := models.RoleExistByUid(account.Uid) | |
28 | + uid := ctx.Value("uid").(string) | |
29 | + ok, role := models.RoleExistByUid(uid) | |
35 | 30 | if !ok { |
36 | 31 | role = models.NewRole(conf.SnowFlack.NextVal()) |
37 | 32 | role.Role.Device = in.Device |
38 | - role.Role.Uid = account.Uid | |
33 | + role.Role.Uid = uid | |
39 | 34 | role.Create() |
40 | 35 | } |
41 | 36 | return &pb.RoleRsp{ |
... | ... | @@ -45,12 +40,8 @@ func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.LoginReq) (* |
45 | 40 | } |
46 | 41 | |
47 | 42 | func (s *GameServer) LoginHandler(ctx context.Context, in *pb.LoginReq) (*pb.RoleRsp, error) { |
48 | - account := utils.CheckAuth(ctx) | |
49 | - if account == nil { | |
50 | - return nil, fmt.Errorf("token error") | |
51 | - } | |
52 | - | |
53 | - ok, role := models.RoleExistByUid(account.Uid) | |
43 | + uid := ctx.Value("uid").(string) | |
44 | + ok, role := models.RoleExistByUid(uid) | |
54 | 45 | if !ok { |
55 | 46 | return &pb.RoleRsp{ |
56 | 47 | Code: 1, | ... | ... |
actions/server.go
... | ... | @@ -2,9 +2,11 @@ package actions |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "context" |
5 | + "fmt" | |
5 | 6 | "google.golang.org/grpc" |
6 | 7 | "google.golang.org/grpc/credentials" |
7 | 8 | "google.golang.org/grpc/reflection" |
9 | + "pro2d/components/jwt" | |
8 | 10 | "pro2d/conf" |
9 | 11 | "pro2d/models" |
10 | 12 | "pro2d/protos/pb" |
... | ... | @@ -86,7 +88,11 @@ func GameServerInterceptor(ctx context.Context, req interface{}, info *grpc.Unar |
86 | 88 | handler grpc.UnaryHandler) (interface{}, error) { |
87 | 89 | |
88 | 90 | //utils.Sugar.Debugf("gRPC method: %s, %v", info.FullMethod, req) |
89 | - | |
91 | + uid := jwt.CheckAuth(ctx) | |
92 | + if uid == ""{ | |
93 | + return nil, fmt.Errorf("token error") | |
94 | + } | |
95 | + context.WithValue(ctx, "uid", uid) | |
90 | 96 | resp, err := handler(ctx, req) |
91 | 97 | return resp, err |
92 | 98 | } | ... | ... |
utils/jwt.go renamed to components/jwt/jwt.go
1 | -package utils | |
1 | +package jwt | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "context" |
5 | 5 | "fmt" |
6 | 6 | "pro2d/conf" |
7 | - "pro2d/protos/pb" | |
7 | + "pro2d/utils" | |
8 | 8 | "time" |
9 | 9 | |
10 | 10 | jwt "github.com/dgrijalva/jwt-go" |
11 | 11 | "google.golang.org/grpc/metadata" |
12 | 12 | ) |
13 | 13 | |
14 | -func CreateToken(account *pb.Account) (tokenString string) { | |
14 | +func CreateToken(uid string) (tokenString string) { | |
15 | 15 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ |
16 | 16 | "iss": "pro2d-app-server", |
17 | 17 | "aud": "pro2d-app-server", |
18 | 18 | "nbf": time.Now().Unix(), |
19 | 19 | "exp": time.Now().Add(time.Hour).Unix(), |
20 | 20 | "sub": "pro2d", |
21 | - "phone": account.Phone, | |
22 | - "uid": account.Uid, | |
21 | + "uid": uid, | |
23 | 22 | }) |
24 | - tokenString, err := token.SignedString([]byte(Pro2DTokenSignedString)) | |
23 | + tokenString, err := token.SignedString([]byte(utils.Pro2DTokenSignedString)) | |
25 | 24 | if err != nil { |
26 | 25 | panic(err) |
27 | 26 | } |
28 | 27 | return tokenString |
29 | 28 | } |
30 | 29 | |
31 | -func ParseToken(tokenStr string)*pb.Account{ | |
30 | +func ParseToken(tokenStr string) string { | |
32 | 31 | var clientClaims Claims |
33 | 32 | token, err := jwt.ParseWithClaims(tokenStr, &clientClaims, func(token *jwt.Token) (interface{}, error) { |
34 | 33 | if token.Header["alg"] != "HS256" { |
35 | 34 | //panic("ErrInvalidAlgorithm") |
36 | - Sugar.Error("ErrInvalidAlgorithm") | |
35 | + utils.Sugar.Error("ErrInvalidAlgorithm") | |
37 | 36 | return nil, nil |
38 | 37 | } |
39 | - return []byte(Pro2DTokenSignedString), nil | |
38 | + return []byte(utils.Pro2DTokenSignedString), nil | |
40 | 39 | }) |
41 | 40 | if err != nil { |
42 | - Sugar.Error("jwt parse error") | |
43 | - return nil | |
41 | + utils.Sugar.Error("jwt parse error") | |
42 | + return "" | |
44 | 43 | } |
45 | 44 | |
46 | 45 | if !token.Valid { |
47 | - Sugar.Error("ErrInvalidToken") | |
48 | - return nil | |
46 | + utils.Sugar.Error("ErrInvalidToken") | |
47 | + return "" | |
49 | 48 | } |
50 | - return &clientClaims.Account | |
49 | + return clientClaims.Uid | |
51 | 50 | } |
52 | 51 | |
53 | 52 | |
54 | 53 | // Claims defines the struct containing the token claims. |
55 | 54 | type Claims struct { |
56 | 55 | jwt.StandardClaims |
57 | - //phone string `json:"phone"` | |
58 | - //uid int64 `json:"uid"` | |
59 | - //device string `json:"device"` | |
60 | - pb.Account | |
56 | + Uid string | |
61 | 57 | } |
62 | 58 | |
63 | 59 | // 从 context 的 metadata 中,取出 token |
... | ... | @@ -75,11 +71,11 @@ func getTokenFromContext(ctx context.Context) (string, error) { |
75 | 71 | return token[0], nil |
76 | 72 | } |
77 | 73 | |
78 | -func CheckAuth(ctx context.Context) *pb.Account{ | |
74 | +func CheckAuth(ctx context.Context) string { | |
79 | 75 | tokenStr, err := getTokenFromContext(ctx) |
80 | 76 | if err != nil { |
81 | - Sugar.Errorf("get token from context error") | |
82 | - return nil | |
77 | + utils.Sugar.Errorf("get token from context error") | |
78 | + return "" | |
83 | 79 | } |
84 | 80 | return ParseToken(tokenStr) |
85 | 81 | } | ... | ... |
utils/jwt_test.go renamed to components/jwt/jwt_test.go
1 | -package utils | |
1 | +package jwt | |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "fmt" |
... | ... | @@ -12,7 +12,7 @@ func TestCreateToken(t *testing.T) { |
12 | 12 | Password: "123456", |
13 | 13 | Uid: "12312", |
14 | 14 | } |
15 | - token := CreateToken(account) | |
15 | + token := CreateToken(account.Uid) | |
16 | 16 | ac := ParseToken(token) |
17 | 17 | fmt.Println("token: ", token, "\nac: ", ac) |
18 | 18 | } | ... | ... |
conf/conf.yaml
test/client.go
... | ... | @@ -7,6 +7,7 @@ import ( |
7 | 7 | "fmt" |
8 | 8 | "google.golang.org/grpc" |
9 | 9 | "google.golang.org/grpc/credentials" |
10 | + "pro2d/components/jwt" | |
10 | 11 | _ "pro2d/conf" |
11 | 12 | "pro2d/protos/pb" |
12 | 13 | "pro2d/utils" |
... | ... | @@ -32,7 +33,7 @@ func Register(c pb.LoginClient, phone, password string) error { |
32 | 33 | func Login(loginUri, token, uid string) { |
33 | 34 | var opts []grpc.DialOption |
34 | 35 | // 指定自定义认证 |
35 | - opts = append(opts, grpc.WithPerRPCCredentials(&utils.AuthToken{Token: token})) | |
36 | + opts = append(opts, grpc.WithPerRPCCredentials(&jwt.AuthToken{Token: token})) | |
36 | 37 | if TLS { |
37 | 38 | // TLS连接 |
38 | 39 | creds, err := credentials.NewClientTLSFromFile("keys/server.pem", ServerName) | ... | ... |
test/tlsclient.go
... | ... | @@ -4,9 +4,27 @@ import ( |
4 | 4 | "context" |
5 | 5 | "google.golang.org/grpc" |
6 | 6 | "google.golang.org/grpc/credentials" |
7 | + "google.golang.org/protobuf/types/known/emptypb" | |
7 | 8 | "log" |
9 | + "pro2d/components/jwt" | |
10 | + _ "pro2d/conf" | |
8 | 11 | "pro2d/protos/pb" |
12 | + "pro2d/utils" | |
9 | 13 | ) |
14 | +// AuthToken 自定义认证 客户端使用 | |
15 | +type CustomToken struct { | |
16 | +} | |
17 | + | |
18 | +func (c CustomToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { | |
19 | + return map[string]string{ | |
20 | + "appId": "100", | |
21 | + "appKey": "token", | |
22 | + }, nil | |
23 | +} | |
24 | + | |
25 | +func (c CustomToken) RequireTransportSecurity() bool { | |
26 | + return true | |
27 | +} | |
10 | 28 | |
11 | 29 | func main() { |
12 | 30 | var opts []grpc.DialOption |
... | ... | @@ -19,7 +37,25 @@ func main() { |
19 | 37 | conn, err := grpc.Dial("localhost:8948", opts...) |
20 | 38 | |
21 | 39 | helloClient := pb.NewHelloClient(conn) |
22 | - rsp, err := helloClient.SayHello(context.TODO(), &pb.HelloWorld{Msg: "hello world"}) | |
40 | + token, err := helloClient.CreateToken(context.TODO(), &pb.Login{ | |
41 | + Login: "login", | |
42 | + Password: "123456", | |
43 | + }) | |
44 | + if err != nil { | |
45 | + log.Fatal(err) | |
46 | + return | |
47 | + } | |
48 | + utils.Sugar.Debugf("token: %s", token.Token) | |
49 | + | |
50 | + opts = append(opts, grpc.WithPerRPCCredentials(&jwt.AuthToken{Token: token.Token})) | |
51 | + conn2, err := grpc.Dial("localhost:8948",opts...) | |
52 | + if err != nil { | |
53 | + log.Fatal(err) | |
54 | + return | |
55 | + } | |
56 | + | |
57 | + helloClient2 := pb.NewHelloClient(conn2) | |
58 | + rsp, err := helloClient2.SayHello(context.TODO(), &emptypb.Empty{}) | |
23 | 59 | if err != nil { |
24 | 60 | log.Fatal(err) |
25 | 61 | } | ... | ... |
test/tlsserver.go
... | ... | @@ -2,10 +2,16 @@ package main |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "context" |
5 | + "fmt" | |
5 | 6 | "google.golang.org/grpc" |
7 | + "google.golang.org/grpc/codes" | |
6 | 8 | "google.golang.org/grpc/credentials" |
9 | + "google.golang.org/grpc/metadata" | |
10 | + "google.golang.org/grpc/status" | |
11 | + "google.golang.org/protobuf/types/known/emptypb" | |
7 | 12 | "log" |
8 | 13 | "net" |
14 | + "pro2d/components/jwt" | |
9 | 15 | "pro2d/protos/pb" |
10 | 16 | ) |
11 | 17 | |
... | ... | @@ -13,10 +19,50 @@ type Server struct { |
13 | 19 | pb.UnimplementedHelloServer |
14 | 20 | } |
15 | 21 | |
16 | -func (s *Server) SayHello(ctx context.Context, in *pb.HelloWorld) (*pb.HelloWorld, error) { | |
17 | - return in, nil | |
22 | +func (s *Server) CreateToken(ctx context.Context, in *pb.Login) (*pb.TokenInfo, error) { | |
23 | + if in.Login == "login" && in.Password == "123456" { | |
24 | + return &pb.TokenInfo{Token: jwt.CreateToken(in.Login)}, nil | |
25 | + } | |
26 | + return nil, fmt.Errorf("login error") | |
18 | 27 | } |
19 | 28 | |
29 | +//func (s *Server) SayHello(ctx context.Context, empty *emptypb.Empty) (*pb.HelloWorld, error) { | |
30 | +// md, ok := metadata.FromIncomingContext(ctx) | |
31 | +// if !ok { | |
32 | +// return nil, status.Errorf(codes.Unauthenticated,"ErrNoMetadataInContext") | |
33 | +// } | |
34 | +// // md 的类型是 type MD map[string][]string | |
35 | +// token, ok := md["authorization"] | |
36 | +// if !ok || len(token) == 0 { | |
37 | +// return nil, status.Errorf(codes.Unauthenticated,"ErrNoAuthorizationInMetadata") | |
38 | +// } | |
39 | +// login := jwt.ParseToken(token[0]) | |
40 | +// return &pb.HelloWorld{Msg: "Hello world: " + login}, nil | |
41 | +//} | |
42 | + | |
43 | +func (s *Server) SayHello(ctx context.Context, empty *emptypb.Empty) (*pb.HelloWorld, error) { | |
44 | + md, ok := metadata.FromIncomingContext(ctx) | |
45 | + if !ok { | |
46 | + return nil, status.Errorf(codes.Unauthenticated, "无Token认证信息") | |
47 | + } | |
48 | + var ( | |
49 | + appId string | |
50 | + appKey string | |
51 | + ) | |
52 | + if val, ok := md["appid"]; ok { | |
53 | + appId = val[0] | |
54 | + } | |
55 | + | |
56 | + if val, ok := md["appkey"]; ok { | |
57 | + appKey = val[0] | |
58 | + } | |
59 | + | |
60 | + if appId != "100" || appKey != "token" { | |
61 | + return nil, status.Errorf(codes.Unauthenticated, "Token认证信息无效: appid=%s, appkey=%s", appId, appKey) | |
62 | + } | |
63 | + | |
64 | + return &pb.HelloWorld{Msg: "Hello world"}, nil | |
65 | +} | |
20 | 66 | func main() { |
21 | 67 | // 监听本地端口 |
22 | 68 | listener, err := net.Listen("tcp", ":8948") | ... | ... |