Commit 563acaf72e78686be3aeac31069439365896a141
1 parent
f7f4beb5
在拦截器中认证jwt
Showing
9 changed files
with
85 additions
and
118 deletions
Show diff stats
actions/accountaction.go
... | ... | @@ -9,40 +9,33 @@ import ( |
9 | 9 | "pro2d/utils" |
10 | 10 | ) |
11 | 11 | |
12 | -func (s *AccountServer) RegisterHandler(ctx context.Context, in *pb.Register) (*pb.PubRsp, error) { | |
12 | +func (s *LoginServer) RegisterHandler(ctx context.Context, in *pb.Register) (*pb.RegisterRsp, error) { | |
13 | 13 | ok, account := models.AccountExistByPhone(in.Phone) |
14 | 14 | if !ok { |
15 | 15 | account.Phone = in.Phone |
16 | 16 | account.Password = utils.Md5V(in.Password) |
17 | 17 | account.Uid = conf.SnowFlack.NextValStr() |
18 | - account.Device = "123123" | |
19 | 18 | account.Create() |
20 | 19 | }else { |
21 | 20 | return nil, fmt.Errorf("1") |
22 | 21 | } |
23 | 22 | |
24 | - return &pb.PubRsp{ | |
23 | + return &pb.RegisterRsp{ | |
25 | 24 | Code: 0, |
26 | 25 | }, nil |
27 | 26 | } |
28 | 27 | |
29 | -func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountInfo) (*pb.CreateTokenRsp, error) { | |
28 | +func (s *LoginServer) CreateTokenHandler(ctx context.Context, in *pb.Account) (*pb.CreateTokenRsp, error) { | |
30 | 29 | m := models.NewAccount(in.Phone) |
31 | 30 | if err := m.Load(); err != nil { |
32 | 31 | return &pb.CreateTokenRsp{ |
33 | - Rsp: &pb.PubRsp{ | |
34 | - Code: 1, | |
35 | - Msg: err.Error(), | |
36 | - }, | |
32 | + Code: 1, | |
37 | 33 | }, nil |
38 | 34 | } |
39 | 35 | |
40 | 36 | if m.Password != utils.Md5V(in.Password) { |
41 | 37 | return &pb.CreateTokenRsp{ |
42 | - Rsp: &pb.PubRsp{ | |
43 | - Code: 2, | |
44 | - Msg: "password error", | |
45 | - }, | |
38 | + Code: 2, | |
46 | 39 | }, nil |
47 | 40 | } |
48 | 41 | |
... | ... | @@ -57,10 +50,9 @@ func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountIn |
57 | 50 | } |
58 | 51 | |
59 | 52 | return &pb.CreateTokenRsp{ |
60 | - Rsp: &pb.PubRsp{ | |
61 | - Code: 0, | |
62 | - }, | |
63 | - Token: utils.CreateToken(m.AccountInfo), | |
53 | + Code: 0, | |
54 | + Uid: m.Uid, | |
55 | + Token: utils.CreateToken(m.Account), | |
64 | 56 | GameService: gameInfo, |
65 | 57 | }, nil |
66 | 58 | } | ... | ... |
actions/roleaction.go
... | ... | @@ -3,85 +3,50 @@ package actions |
3 | 3 | import ( |
4 | 4 | "context" |
5 | 5 | "errors" |
6 | - "fmt" | |
7 | 6 | "google.golang.org/grpc/metadata" |
7 | + "google.golang.org/protobuf/types/known/emptypb" | |
8 | 8 | "pro2d/conf" |
9 | 9 | "pro2d/models" |
10 | 10 | "pro2d/protos/pb" |
11 | 11 | "pro2d/utils" |
12 | 12 | ) |
13 | 13 | |
14 | -func (s *GameServer) HeartBeatHandler(ctx context.Context, in *pb.Token) (*pb.PubRsp, error) { | |
14 | +func (s *GameServer) HeartBeatHandler(ctx context.Context, empty *emptypb.Empty) (*pb.HeartRsp, error) { | |
15 | 15 | utils.Sugar.Debugf("HeartBeatHandler被调用!!!") |
16 | 16 | //获取元数据信息 |
17 | - md,ok := metadata.FromIncomingContext(ctx) | |
17 | + _,ok := metadata.FromIncomingContext(ctx) | |
18 | 18 | if !ok { |
19 | 19 | return nil,errors.New("未传输token") |
20 | 20 | } |
21 | - var ( | |
22 | - appId string | |
23 | - appKey string | |
24 | - ) | |
25 | - if val, ok := md["appId"]; ok { | |
26 | - appId = val[0] | |
27 | - } | |
28 | - if val, ok := md["appKey"]; ok { | |
29 | - appKey = val[0] | |
30 | - } | |
31 | - //进行校验的信息是否正确 | |
32 | - if appId != "123" || appKey != "456" { | |
33 | - return nil, errors.New("token传输不正确") | |
34 | - } | |
35 | 21 | |
36 | - return &pb.PubRsp{ | |
22 | + return &pb.HeartRsp{ | |
37 | 23 | Code: 0, |
38 | - Msg: "heart beat successful", | |
39 | 24 | }, nil |
40 | 25 | } |
41 | 26 | |
42 | -func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.Token) (*pb.RoleRsp, error) { | |
43 | - account := utils.ParseToken(in.Token) | |
44 | - if account == nil { | |
45 | - return nil, fmt.Errorf("1") | |
46 | - } | |
47 | - ok, role := models.RoleExistByUid(account.Uid) | |
27 | +func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.LoginReq) (*pb.RoleRsp, error) { | |
28 | + ok, role := models.RoleExistByUid(in.Uid) | |
48 | 29 | if !ok { |
49 | 30 | role = models.NewRole(conf.SnowFlack.NextVal()) |
50 | - role.Role.Device = account.Device | |
51 | - role.Role.Uid = account.Uid | |
31 | + role.Role.Device = in.Device | |
32 | + role.Role.Uid = in.Uid | |
52 | 33 | role.Create() |
53 | - | |
54 | 34 | } |
55 | 35 | return &pb.RoleRsp{ |
56 | - Rsp: &pb.PubRsp{ | |
57 | - Code: 0, | |
58 | - Msg: "successful", | |
59 | - }, | |
36 | + Code: 0, | |
60 | 37 | Role: role.Role, |
61 | 38 | }, nil |
62 | 39 | } |
63 | 40 | |
64 | -func (s *GameServer) LoginHandler(ctx context.Context, in *pb.Token) (*pb.RoleRsp, error) { | |
65 | - account := utils.ParseToken(in.Token) | |
66 | - if account == nil { | |
67 | - return nil, fmt.Errorf("token is error") | |
68 | - } | |
69 | - utils.Sugar.Debugf("login account: %v", account) | |
70 | - ok, role := models.RoleExistByUid(account.Uid) | |
41 | +func (s *GameServer) LoginHandler(ctx context.Context, in *pb.LoginReq) (*pb.RoleRsp, error) { | |
42 | + ok, role := models.RoleExistByUid(in.Uid) | |
71 | 43 | if !ok { |
72 | 44 | return &pb.RoleRsp{ |
73 | - Rsp: &pb.PubRsp{ | |
74 | - Code: 1, | |
75 | - Msg: "role not exist", | |
76 | - }, | |
77 | - | |
45 | + Code: 1, | |
78 | 46 | }, nil |
79 | 47 | } |
80 | 48 | return &pb.RoleRsp{ |
81 | - Rsp: &pb.PubRsp{ | |
82 | - Code: 0, | |
83 | - Msg: "successful", | |
84 | - }, | |
49 | + Code: 0, | |
85 | 50 | Role: role.Role, |
86 | 51 | Hero: models.GetHeros(role.Heros), |
87 | 52 | }, nil | ... | ... |
actions/server.go
... | ... | @@ -2,6 +2,7 @@ package actions |
2 | 2 | |
3 | 3 | import ( |
4 | 4 | "context" |
5 | + "fmt" | |
5 | 6 | "google.golang.org/grpc" |
6 | 7 | "google.golang.org/grpc/reflection" |
7 | 8 | "pro2d/conf" |
... | ... | @@ -10,13 +11,13 @@ import ( |
10 | 11 | "pro2d/utils" |
11 | 12 | ) |
12 | 13 | |
13 | -type AccountServer struct{ | |
14 | - pb.UnimplementedAccountServer | |
14 | +type LoginServer struct{ | |
15 | + pb.UnsafeLoginServer | |
15 | 16 | *BasicServer |
16 | 17 | } |
17 | 18 | |
18 | -func NewAccountServer() *AccountServer { | |
19 | - return &AccountServer{ | |
19 | +func NewAccountServer() *LoginServer { | |
20 | + return &LoginServer{ | |
20 | 21 | BasicServer: NewServer(), |
21 | 22 | } |
22 | 23 | } |
... | ... | @@ -30,7 +31,7 @@ func AccountServerInterceptor(ctx context.Context, req interface{}, info *grpc.U |
30 | 31 | return resp, err |
31 | 32 | } |
32 | 33 | |
33 | -func (s *AccountServer)Start() error { | |
34 | +func (s *LoginServer)Start() error { | |
34 | 35 | lis, err := s.BasicServer.Start(conf.GlobalConf.AccountConf) |
35 | 36 | if err != nil { |
36 | 37 | return err |
... | ... | @@ -41,17 +42,17 @@ func (s *AccountServer)Start() error { |
41 | 42 | //new一个grpc |
42 | 43 | s.GrpcServer = grpc.NewServer(grpc.UnaryInterceptor(AccountServerInterceptor)) |
43 | 44 | |
44 | - pb.RegisterAccountServer(s.GrpcServer, s) | |
45 | + pb.RegisterLoginServer(s.GrpcServer, s) | |
45 | 46 | reflection.Register(s.GrpcServer) //在给定的gRPC服务器上注册服务器反射服务 |
46 | 47 | |
47 | 48 | // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 |
48 | 49 | // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 |
49 | - utils.Sugar.Debugf("Start AccountServer listening on %d", conf.GlobalConf.AccountConf.Port) | |
50 | + utils.Sugar.Debugf("Start LoginServer listening on %d", conf.GlobalConf.AccountConf.Port) | |
50 | 51 | |
51 | 52 | return s.GrpcServer.Serve(lis) |
52 | 53 | } |
53 | 54 | |
54 | -func (s *AccountServer)Stop() { | |
55 | +func (s *LoginServer)Stop() { | |
55 | 56 | s.BasicServer.Stop() |
56 | 57 | } |
57 | 58 | |
... | ... | @@ -69,7 +70,12 @@ func NewGameServer() *GameServer { |
69 | 70 | func GameServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, |
70 | 71 | handler grpc.UnaryHandler) (interface{}, error) { |
71 | 72 | |
72 | - utils.Sugar.Debugf("gRPC method: %s, %v", info.FullMethod, req) | |
73 | + //utils.Sugar.Debugf("gRPC method: %s, %v", info.FullMethod, req) | |
74 | + acc := utils.CheckAuth(ctx) | |
75 | + if acc == nil { | |
76 | + return nil, fmt.Errorf("token error") | |
77 | + } | |
78 | + | |
73 | 79 | resp, err := handler(ctx, req) |
74 | 80 | return resp, err |
75 | 81 | } | ... | ... |
... | ... | @@ -5,6 +5,7 @@ go 1.17 |
5 | 5 | require ( |
6 | 6 | github.com/dgrijalva/jwt-go v3.2.0+incompatible |
7 | 7 | github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b |
8 | + go.etcd.io/etcd/api/v3 v3.5.2 | |
8 | 9 | go.etcd.io/etcd/client/v3 v3.5.2 |
9 | 10 | go.mongodb.org/mongo-driver v1.8.3 |
10 | 11 | go.uber.org/zap v1.17.0 |
... | ... | @@ -27,7 +28,6 @@ require ( |
27 | 28 | github.com/xdg-go/scram v1.0.2 // indirect |
28 | 29 | github.com/xdg-go/stringprep v1.0.2 // indirect |
29 | 30 | github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect |
30 | - go.etcd.io/etcd/api/v3 v3.5.2 // indirect | |
31 | 31 | go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect |
32 | 32 | go.uber.org/atomic v1.7.0 // indirect |
33 | 33 | go.uber.org/multierr v1.6.0 // indirect | ... | ... |
models/account.go
... | ... | @@ -7,7 +7,7 @@ import ( |
7 | 7 | |
8 | 8 | type AccountModel struct { |
9 | 9 | *db.MgoColl |
10 | - *pb.AccountInfo | |
10 | + *pb.Account | |
11 | 11 | } |
12 | 12 | |
13 | 13 | func AccountExistByPhone(phone string) (bool, *AccountModel){ |
... | ... | @@ -19,12 +19,12 @@ func AccountExistByPhone(phone string) (bool, *AccountModel){ |
19 | 19 | } |
20 | 20 | |
21 | 21 | func NewAccount(phone string) *AccountModel { |
22 | - ac := &pb.AccountInfo{ | |
22 | + ac := &pb.Account{ | |
23 | 23 | Phone: phone, |
24 | 24 | } |
25 | 25 | account := &AccountModel{ |
26 | 26 | MgoColl: db.NewMongoColl(phone, ac), |
27 | - AccountInfo: ac, | |
27 | + Account: ac, | |
28 | 28 | } |
29 | 29 | |
30 | 30 | return account | ... | ... |
models/init.go
test/client.go
... | ... | @@ -9,7 +9,7 @@ import ( |
9 | 9 | "pro2d/utils" |
10 | 10 | ) |
11 | 11 | |
12 | -func Register(c pb.AccountClient, phone, password string) error { | |
12 | +func Register(c pb.LoginClient, phone, password string) error { | |
13 | 13 | r, err := c.RegisterHandler(context.Background(), &pb.Register{ |
14 | 14 | Phone: "17683852936", |
15 | 15 | Password: "123456", |
... | ... | @@ -20,14 +20,17 @@ func Register(c pb.AccountClient, phone, password string) error { |
20 | 20 | return err |
21 | 21 | } |
22 | 22 | if r.Code != 0 { |
23 | - return fmt.Errorf("%s", r.Msg) | |
23 | + return fmt.Errorf("register fail") | |
24 | 24 | } |
25 | 25 | utils.Sugar.Debug("register success") |
26 | 26 | return nil |
27 | 27 | } |
28 | 28 | |
29 | -func Login(loginUri, token string) { | |
30 | - gameConn, err := grpc.Dial(loginUri, grpc.WithInsecure() ) | |
29 | +func Login(loginUri, token, uid string) { | |
30 | + var opts []grpc.DialOption | |
31 | + // 指定自定义认证 | |
32 | + opts = append(opts, grpc.WithPerRPCCredentials(&utils.AuthToken{Token: token}), grpc.WithInsecure()) | |
33 | + gameConn, err := grpc.Dial(loginUri, opts...) | |
31 | 34 | if err != nil { |
32 | 35 | utils.Sugar.Errorf("game conn err: %v", err) |
33 | 36 | return |
... | ... | @@ -36,8 +39,9 @@ func Login(loginUri, token string) { |
36 | 39 | |
37 | 40 | client:= pb.NewGameClient(gameConn) |
38 | 41 | var role *pb.Role |
39 | - loginRsp, err := client.LoginHandler(context.Background(), &pb.Token{ | |
40 | - Token: token, | |
42 | + loginRsp, err := client.LoginHandler(context.Background(), &pb.LoginReq{ | |
43 | + Uid: uid, | |
44 | + Device: "111111", | |
41 | 45 | }) |
42 | 46 | |
43 | 47 | if err != nil { |
... | ... | @@ -46,14 +50,14 @@ func Login(loginUri, token string) { |
46 | 50 | } |
47 | 51 | role = loginRsp.Role |
48 | 52 | |
49 | - if loginRsp.Rsp.Code != 0 { | |
50 | - utils.Sugar.Debugf("login rsp: %v", loginRsp.Rsp.Msg) | |
51 | - createRole, err := client.CreateRoleHandler(context.Background(), &pb.Token{Token: token}) | |
53 | + if loginRsp.Code != 0 { | |
54 | + utils.Sugar.Debugf("login fail, role not exist") | |
55 | + createRole, err := client.CreateRoleHandler(context.Background(), &pb.LoginReq{Uid: uid, Device: "11111"}) | |
52 | 56 | if err != nil { |
53 | 57 | utils.Sugar.Errorf("create role err: %v", err) |
54 | 58 | return |
55 | 59 | } |
56 | - utils.Sugar.Debug("create role rsp: ", createRole.Rsp.Code, createRole.Rsp.Msg) | |
60 | + utils.Sugar.Debug("create role rsp: ", createRole.Code) | |
57 | 61 | role = createRole.Role |
58 | 62 | } |
59 | 63 | |
... | ... | @@ -67,13 +71,13 @@ func main() { |
67 | 71 | return |
68 | 72 | } |
69 | 73 | defer conn.Close() |
70 | - c := pb.NewAccountClient(conn) | |
71 | - //err = Register(c,"17683852936", "123456") | |
74 | + c := pb.NewLoginClient(conn) | |
75 | + err = Register(c,"17683852936", "123456") | |
72 | 76 | //if err != nil { |
73 | 77 | // utils.Sugar.Errorf("register err: %v", err) |
74 | 78 | // return |
75 | 79 | //} |
76 | - rsp, err := c.CreateTokenHandler(context.Background(), &pb.AccountInfo{ | |
80 | + rsp, err := c.CreateTokenHandler(context.Background(), &pb.Account{ | |
77 | 81 | Phone: "17683852936", |
78 | 82 | Password: "123456", |
79 | 83 | }) |
... | ... | @@ -83,12 +87,12 @@ func main() { |
83 | 87 | return |
84 | 88 | } |
85 | 89 | |
86 | - if rsp.Rsp.Code != 0 { | |
87 | - utils.Sugar.Errorf("createtoken err: %v", rsp.Rsp.Msg) | |
90 | + if rsp.Code != 0 { | |
91 | + utils.Sugar.Errorf("createtoken err" ) | |
88 | 92 | return |
89 | 93 | } |
90 | 94 | |
91 | 95 | if len(rsp.GameService) >0 { |
92 | - Login(rsp.GameService[0].Address, rsp.Token) | |
96 | + Login(rsp.GameService[0].Address, rsp.Token, rsp.Uid) | |
93 | 97 | } |
94 | 98 | } | ... | ... |
utils/jwt.go
... | ... | @@ -10,7 +10,7 @@ import ( |
10 | 10 | "google.golang.org/grpc/metadata" |
11 | 11 | ) |
12 | 12 | |
13 | -func CreateToken(account *pb.AccountInfo) (tokenString string) { | |
13 | +func CreateToken(account *pb.Account) (tokenString string) { | |
14 | 14 | token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ |
15 | 15 | "iss": "pro2d-app-server", |
16 | 16 | "aud": "pro2d-app-server", |
... | ... | @@ -19,7 +19,6 @@ func CreateToken(account *pb.AccountInfo) (tokenString string) { |
19 | 19 | "sub": "pro2d", |
20 | 20 | "phone": account.Phone, |
21 | 21 | "uid": account.Uid, |
22 | - "device": account.Device, | |
23 | 22 | }) |
24 | 23 | tokenString, err := token.SignedString([]byte(Pro2DTokenSignedString)) |
25 | 24 | if err != nil { |
... | ... | @@ -28,7 +27,7 @@ func CreateToken(account *pb.AccountInfo) (tokenString string) { |
28 | 27 | return tokenString |
29 | 28 | } |
30 | 29 | |
31 | -func ParseToken(tokenStr string)*pb.AccountInfo { | |
30 | +func ParseToken(tokenStr string)*pb.Account{ | |
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" { |
... | ... | @@ -47,23 +46,9 @@ func ParseToken(tokenStr string)*pb.AccountInfo { |
47 | 46 | Sugar.Error("ErrInvalidToken") |
48 | 47 | return nil |
49 | 48 | } |
50 | - return &clientClaims.AccountInfo | |
49 | + return &clientClaims.Account | |
51 | 50 | } |
52 | 51 | |
53 | -// AuthToken 自定义认证 | |
54 | -type AuthToken struct { | |
55 | - Token string | |
56 | -} | |
57 | - | |
58 | -func (c AuthToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { | |
59 | - return map[string]string{ | |
60 | - "authorization": c.Token, | |
61 | - }, nil | |
62 | -} | |
63 | - | |
64 | -func (c AuthToken) RequireTransportSecurity() bool { | |
65 | - return false | |
66 | -} | |
67 | 52 | |
68 | 53 | // Claims defines the struct containing the token claims. |
69 | 54 | type Claims struct { |
... | ... | @@ -71,7 +56,7 @@ type Claims struct { |
71 | 56 | //phone string `json:"phone"` |
72 | 57 | //uid int64 `json:"uid"` |
73 | 58 | //device string `json:"device"` |
74 | - pb.AccountInfo | |
59 | + pb.Account | |
75 | 60 | } |
76 | 61 | |
77 | 62 | // 从 context 的 metadata 中,取出 token |
... | ... | @@ -89,10 +74,26 @@ func getTokenFromContext(ctx context.Context) (string, error) { |
89 | 74 | return token[0], nil |
90 | 75 | } |
91 | 76 | |
92 | -func CheckAuth(ctx context.Context) *pb.AccountInfo { | |
77 | +func CheckAuth(ctx context.Context) *pb.Account{ | |
93 | 78 | tokenStr, err := getTokenFromContext(ctx) |
94 | 79 | if err != nil { |
95 | - panic("get token from context error") | |
80 | + Sugar.Errorf("get token from context error") | |
81 | + return nil | |
96 | 82 | } |
97 | 83 | return ParseToken(tokenStr) |
84 | +} | |
85 | + | |
86 | +// AuthToken 自定义认证 客户端使用 | |
87 | +type AuthToken struct { | |
88 | + Token string | |
89 | +} | |
90 | + | |
91 | +func (c AuthToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { | |
92 | + return map[string]string{ | |
93 | + "authorization": c.Token, | |
94 | + }, nil | |
95 | +} | |
96 | + | |
97 | +func (c AuthToken) RequireTransportSecurity() bool { | |
98 | + return false | |
98 | 99 | } |
99 | 100 | \ No newline at end of file | ... | ... |
utils/jwt_test.go
... | ... | @@ -7,11 +7,10 @@ import ( |
7 | 7 | ) |
8 | 8 | |
9 | 9 | func TestCreateToken(t *testing.T) { |
10 | - account := &pb.AccountInfo{ | |
10 | + account := &pb.Account{ | |
11 | 11 | Phone: "17683852936", |
12 | 12 | Password: "123456", |
13 | - Uid: 12312, | |
14 | - Device: "12312312", | |
13 | + Uid: "12312", | |
15 | 14 | } |
16 | 15 | token := CreateToken(account) |
17 | 16 | ac := ParseToken(token) | ... | ... |