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") |