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,6 +3,7 @@ package actions | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | "fmt" | 5 | "fmt" |
6 | + "pro2d/components/jwt" | ||
6 | "pro2d/conf" | 7 | "pro2d/conf" |
7 | "pro2d/models" | 8 | "pro2d/models" |
8 | "pro2d/protos/pb" | 9 | "pro2d/protos/pb" |
@@ -52,7 +53,7 @@ func (s *LoginServer) CreateTokenHandler(ctx context.Context, in *pb.Account) (* | @@ -52,7 +53,7 @@ func (s *LoginServer) CreateTokenHandler(ctx context.Context, in *pb.Account) (* | ||
52 | return &pb.CreateTokenRsp{ | 53 | return &pb.CreateTokenRsp{ |
53 | Code: 0, | 54 | Code: 0, |
54 | Uid: m.Uid, | 55 | Uid: m.Uid, |
55 | - Token: utils.CreateToken(m.Account), | 56 | + Token: jwt.CreateToken(m.Account.Uid), |
56 | GameService: gameInfo, | 57 | GameService: gameInfo, |
57 | }, nil | 58 | }, nil |
58 | } | 59 | } |
actions/roleaction.go
@@ -3,7 +3,6 @@ package actions | @@ -3,7 +3,6 @@ package actions | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | "errors" | 5 | "errors" |
6 | - "fmt" | ||
7 | "google.golang.org/grpc/metadata" | 6 | "google.golang.org/grpc/metadata" |
8 | "google.golang.org/protobuf/types/known/emptypb" | 7 | "google.golang.org/protobuf/types/known/emptypb" |
9 | "pro2d/conf" | 8 | "pro2d/conf" |
@@ -26,16 +25,12 @@ func (s *GameServer) HeartBeatHandler(ctx context.Context, empty *emptypb.Empty) | @@ -26,16 +25,12 @@ func (s *GameServer) HeartBeatHandler(ctx context.Context, empty *emptypb.Empty) | ||
26 | } | 25 | } |
27 | 26 | ||
28 | func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.LoginReq) (*pb.RoleRsp, error) { | 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 | if !ok { | 30 | if !ok { |
36 | role = models.NewRole(conf.SnowFlack.NextVal()) | 31 | role = models.NewRole(conf.SnowFlack.NextVal()) |
37 | role.Role.Device = in.Device | 32 | role.Role.Device = in.Device |
38 | - role.Role.Uid = account.Uid | 33 | + role.Role.Uid = uid |
39 | role.Create() | 34 | role.Create() |
40 | } | 35 | } |
41 | return &pb.RoleRsp{ | 36 | return &pb.RoleRsp{ |
@@ -45,12 +40,8 @@ func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.LoginReq) (* | @@ -45,12 +40,8 @@ func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.LoginReq) (* | ||
45 | } | 40 | } |
46 | 41 | ||
47 | func (s *GameServer) LoginHandler(ctx context.Context, in *pb.LoginReq) (*pb.RoleRsp, error) { | 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 | if !ok { | 45 | if !ok { |
55 | return &pb.RoleRsp{ | 46 | return &pb.RoleRsp{ |
56 | Code: 1, | 47 | Code: 1, |
actions/server.go
@@ -2,9 +2,11 @@ package actions | @@ -2,9 +2,11 @@ package actions | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | + "fmt" | ||
5 | "google.golang.org/grpc" | 6 | "google.golang.org/grpc" |
6 | "google.golang.org/grpc/credentials" | 7 | "google.golang.org/grpc/credentials" |
7 | "google.golang.org/grpc/reflection" | 8 | "google.golang.org/grpc/reflection" |
9 | + "pro2d/components/jwt" | ||
8 | "pro2d/conf" | 10 | "pro2d/conf" |
9 | "pro2d/models" | 11 | "pro2d/models" |
10 | "pro2d/protos/pb" | 12 | "pro2d/protos/pb" |
@@ -86,7 +88,11 @@ func GameServerInterceptor(ctx context.Context, req interface{}, info *grpc.Unar | @@ -86,7 +88,11 @@ func GameServerInterceptor(ctx context.Context, req interface{}, info *grpc.Unar | ||
86 | handler grpc.UnaryHandler) (interface{}, error) { | 88 | handler grpc.UnaryHandler) (interface{}, error) { |
87 | 89 | ||
88 | //utils.Sugar.Debugf("gRPC method: %s, %v", info.FullMethod, req) | 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 | resp, err := handler(ctx, req) | 96 | resp, err := handler(ctx, req) |
91 | return resp, err | 97 | return resp, err |
92 | } | 98 | } |
utils/jwt.go renamed to components/jwt/jwt.go
1 | -package utils | 1 | +package jwt |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | "fmt" | 5 | "fmt" |
6 | "pro2d/conf" | 6 | "pro2d/conf" |
7 | - "pro2d/protos/pb" | 7 | + "pro2d/utils" |
8 | "time" | 8 | "time" |
9 | 9 | ||
10 | jwt "github.com/dgrijalva/jwt-go" | 10 | jwt "github.com/dgrijalva/jwt-go" |
11 | "google.golang.org/grpc/metadata" | 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 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ | 15 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ |
16 | "iss": "pro2d-app-server", | 16 | "iss": "pro2d-app-server", |
17 | "aud": "pro2d-app-server", | 17 | "aud": "pro2d-app-server", |
18 | "nbf": time.Now().Unix(), | 18 | "nbf": time.Now().Unix(), |
19 | "exp": time.Now().Add(time.Hour).Unix(), | 19 | "exp": time.Now().Add(time.Hour).Unix(), |
20 | "sub": "pro2d", | 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 | if err != nil { | 24 | if err != nil { |
26 | panic(err) | 25 | panic(err) |
27 | } | 26 | } |
28 | return tokenString | 27 | return tokenString |
29 | } | 28 | } |
30 | 29 | ||
31 | -func ParseToken(tokenStr string)*pb.Account{ | 30 | +func ParseToken(tokenStr string) string { |
32 | var clientClaims Claims | 31 | var clientClaims Claims |
33 | token, err := jwt.ParseWithClaims(tokenStr, &clientClaims, func(token *jwt.Token) (interface{}, error) { | 32 | token, err := jwt.ParseWithClaims(tokenStr, &clientClaims, func(token *jwt.Token) (interface{}, error) { |
34 | if token.Header["alg"] != "HS256" { | 33 | if token.Header["alg"] != "HS256" { |
35 | //panic("ErrInvalidAlgorithm") | 34 | //panic("ErrInvalidAlgorithm") |
36 | - Sugar.Error("ErrInvalidAlgorithm") | 35 | + utils.Sugar.Error("ErrInvalidAlgorithm") |
37 | return nil, nil | 36 | return nil, nil |
38 | } | 37 | } |
39 | - return []byte(Pro2DTokenSignedString), nil | 38 | + return []byte(utils.Pro2DTokenSignedString), nil |
40 | }) | 39 | }) |
41 | if err != nil { | 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 | if !token.Valid { | 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 | // Claims defines the struct containing the token claims. | 53 | // Claims defines the struct containing the token claims. |
55 | type Claims struct { | 54 | type Claims struct { |
56 | jwt.StandardClaims | 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 | // 从 context 的 metadata 中,取出 token | 59 | // 从 context 的 metadata 中,取出 token |
@@ -75,11 +71,11 @@ func getTokenFromContext(ctx context.Context) (string, error) { | @@ -75,11 +71,11 @@ func getTokenFromContext(ctx context.Context) (string, error) { | ||
75 | return token[0], nil | 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 | tokenStr, err := getTokenFromContext(ctx) | 75 | tokenStr, err := getTokenFromContext(ctx) |
80 | if err != nil { | 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 | return ParseToken(tokenStr) | 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 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
@@ -12,7 +12,7 @@ func TestCreateToken(t *testing.T) { | @@ -12,7 +12,7 @@ func TestCreateToken(t *testing.T) { | ||
12 | Password: "123456", | 12 | Password: "123456", |
13 | Uid: "12312", | 13 | Uid: "12312", |
14 | } | 14 | } |
15 | - token := CreateToken(account) | 15 | + token := CreateToken(account.Uid) |
16 | ac := ParseToken(token) | 16 | ac := ParseToken(token) |
17 | fmt.Println("token: ", token, "\nac: ", ac) | 17 | fmt.Println("token: ", token, "\nac: ", ac) |
18 | } | 18 | } |
conf/conf.yaml
test/client.go
@@ -7,6 +7,7 @@ import ( | @@ -7,6 +7,7 @@ import ( | ||
7 | "fmt" | 7 | "fmt" |
8 | "google.golang.org/grpc" | 8 | "google.golang.org/grpc" |
9 | "google.golang.org/grpc/credentials" | 9 | "google.golang.org/grpc/credentials" |
10 | + "pro2d/components/jwt" | ||
10 | _ "pro2d/conf" | 11 | _ "pro2d/conf" |
11 | "pro2d/protos/pb" | 12 | "pro2d/protos/pb" |
12 | "pro2d/utils" | 13 | "pro2d/utils" |
@@ -32,7 +33,7 @@ func Register(c pb.LoginClient, phone, password string) error { | @@ -32,7 +33,7 @@ func Register(c pb.LoginClient, phone, password string) error { | ||
32 | func Login(loginUri, token, uid string) { | 33 | func Login(loginUri, token, uid string) { |
33 | var opts []grpc.DialOption | 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 | if TLS { | 37 | if TLS { |
37 | // TLS连接 | 38 | // TLS连接 |
38 | creds, err := credentials.NewClientTLSFromFile("keys/server.pem", ServerName) | 39 | creds, err := credentials.NewClientTLSFromFile("keys/server.pem", ServerName) |
test/tlsclient.go
@@ -4,9 +4,27 @@ import ( | @@ -4,9 +4,27 @@ import ( | ||
4 | "context" | 4 | "context" |
5 | "google.golang.org/grpc" | 5 | "google.golang.org/grpc" |
6 | "google.golang.org/grpc/credentials" | 6 | "google.golang.org/grpc/credentials" |
7 | + "google.golang.org/protobuf/types/known/emptypb" | ||
7 | "log" | 8 | "log" |
9 | + "pro2d/components/jwt" | ||
10 | + _ "pro2d/conf" | ||
8 | "pro2d/protos/pb" | 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 | func main() { | 29 | func main() { |
12 | var opts []grpc.DialOption | 30 | var opts []grpc.DialOption |
@@ -19,7 +37,25 @@ func main() { | @@ -19,7 +37,25 @@ func main() { | ||
19 | conn, err := grpc.Dial("localhost:8948", opts...) | 37 | conn, err := grpc.Dial("localhost:8948", opts...) |
20 | 38 | ||
21 | helloClient := pb.NewHelloClient(conn) | 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 | if err != nil { | 59 | if err != nil { |
24 | log.Fatal(err) | 60 | log.Fatal(err) |
25 | } | 61 | } |
test/tlsserver.go
@@ -2,10 +2,16 @@ package main | @@ -2,10 +2,16 @@ package main | ||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "context" | 4 | "context" |
5 | + "fmt" | ||
5 | "google.golang.org/grpc" | 6 | "google.golang.org/grpc" |
7 | + "google.golang.org/grpc/codes" | ||
6 | "google.golang.org/grpc/credentials" | 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 | "log" | 12 | "log" |
8 | "net" | 13 | "net" |
14 | + "pro2d/components/jwt" | ||
9 | "pro2d/protos/pb" | 15 | "pro2d/protos/pb" |
10 | ) | 16 | ) |
11 | 17 | ||
@@ -13,10 +19,50 @@ type Server struct { | @@ -13,10 +19,50 @@ type Server struct { | ||
13 | pb.UnimplementedHelloServer | 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 | func main() { | 66 | func main() { |
21 | // 监听本地端口 | 67 | // 监听本地端口 |
22 | listener, err := net.Listen("tcp", ":8948") | 68 | listener, err := net.Listen("tcp", ":8948") |