Commit 1b1ad555363e65b30856648c32b5185c52237236

Authored by zhangqijia
1 parent 66502d8d

tls测试代码

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
... ... @@ -16,7 +16,7 @@ etcd:
16 16 endpoints:
17 17 - "192.168.0.206:2379"
18 18  
19   -TLS:
  19 +tls:
20 20 status: true
21 21 key: "keys/server.key"
22 22 pem: "keys/server.pem"
... ...
1   -Subproject commit 564441523f2a69a4efeb2116addae2ed926d6e53
  1 +Subproject commit cee7537250bcee3ddd04e03d2d142d6d1ac6417e
... ...
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")
... ...