From 563acaf72e78686be3aeac31069439365896a141 Mon Sep 17 00:00:00 2001 From: zqj <582132116@qq.com> Date: Mon, 21 Feb 2022 16:07:41 +0800 Subject: [PATCH] 在拦截器中认证jwt --- actions/accountaction.go | 24 ++++++++---------------- actions/roleaction.go | 61 +++++++++++++------------------------------------------------ actions/server.go | 24 +++++++++++++++--------- go.mod | 2 +- models/account.go | 6 +++--- models/init.go | 2 +- test/client.go | 36 ++++++++++++++++++++---------------- utils/jwt.go | 43 ++++++++++++++++++++++--------------------- utils/jwt_test.go | 5 ++--- 9 files changed, 85 insertions(+), 118 deletions(-) diff --git a/actions/accountaction.go b/actions/accountaction.go index 0664b08..b06de01 100644 --- a/actions/accountaction.go +++ b/actions/accountaction.go @@ -9,40 +9,33 @@ import ( "pro2d/utils" ) -func (s *AccountServer) RegisterHandler(ctx context.Context, in *pb.Register) (*pb.PubRsp, error) { +func (s *LoginServer) RegisterHandler(ctx context.Context, in *pb.Register) (*pb.RegisterRsp, error) { ok, account := models.AccountExistByPhone(in.Phone) if !ok { account.Phone = in.Phone account.Password = utils.Md5V(in.Password) account.Uid = conf.SnowFlack.NextValStr() - account.Device = "123123" account.Create() }else { return nil, fmt.Errorf("1") } - return &pb.PubRsp{ + return &pb.RegisterRsp{ Code: 0, }, nil } -func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountInfo) (*pb.CreateTokenRsp, error) { +func (s *LoginServer) CreateTokenHandler(ctx context.Context, in *pb.Account) (*pb.CreateTokenRsp, error) { m := models.NewAccount(in.Phone) if err := m.Load(); err != nil { return &pb.CreateTokenRsp{ - Rsp: &pb.PubRsp{ - Code: 1, - Msg: err.Error(), - }, + Code: 1, }, nil } if m.Password != utils.Md5V(in.Password) { return &pb.CreateTokenRsp{ - Rsp: &pb.PubRsp{ - Code: 2, - Msg: "password error", - }, + Code: 2, }, nil } @@ -57,10 +50,9 @@ func (s *AccountServer) CreateTokenHandler(ctx context.Context, in *pb.AccountIn } return &pb.CreateTokenRsp{ - Rsp: &pb.PubRsp{ - Code: 0, - }, - Token: utils.CreateToken(m.AccountInfo), + Code: 0, + Uid: m.Uid, + Token: utils.CreateToken(m.Account), GameService: gameInfo, }, nil } diff --git a/actions/roleaction.go b/actions/roleaction.go index 7412672..bf44153 100644 --- a/actions/roleaction.go +++ b/actions/roleaction.go @@ -3,85 +3,50 @@ package actions import ( "context" "errors" - "fmt" "google.golang.org/grpc/metadata" + "google.golang.org/protobuf/types/known/emptypb" "pro2d/conf" "pro2d/models" "pro2d/protos/pb" "pro2d/utils" ) -func (s *GameServer) HeartBeatHandler(ctx context.Context, in *pb.Token) (*pb.PubRsp, error) { +func (s *GameServer) HeartBeatHandler(ctx context.Context, empty *emptypb.Empty) (*pb.HeartRsp, error) { utils.Sugar.Debugf("HeartBeatHandler被调用!!!") //获取元数据信息 - md,ok := metadata.FromIncomingContext(ctx) + _,ok := metadata.FromIncomingContext(ctx) if !ok { return nil,errors.New("未传输token") } - var ( - appId string - appKey string - ) - if val, ok := md["appId"]; ok { - appId = val[0] - } - if val, ok := md["appKey"]; ok { - appKey = val[0] - } - //进行校验的信息是否正确 - if appId != "123" || appKey != "456" { - return nil, errors.New("token传输不正确") - } - return &pb.PubRsp{ + return &pb.HeartRsp{ Code: 0, - Msg: "heart beat successful", }, nil } -func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.Token) (*pb.RoleRsp, error) { - account := utils.ParseToken(in.Token) - if account == nil { - return nil, fmt.Errorf("1") - } - ok, role := models.RoleExistByUid(account.Uid) +func (s *GameServer) CreateRoleHandler(ctx context.Context, in *pb.LoginReq) (*pb.RoleRsp, error) { + ok, role := models.RoleExistByUid(in.Uid) if !ok { role = models.NewRole(conf.SnowFlack.NextVal()) - role.Role.Device = account.Device - role.Role.Uid = account.Uid + role.Role.Device = in.Device + role.Role.Uid = in.Uid role.Create() - } return &pb.RoleRsp{ - Rsp: &pb.PubRsp{ - Code: 0, - Msg: "successful", - }, + Code: 0, Role: role.Role, }, nil } -func (s *GameServer) LoginHandler(ctx context.Context, in *pb.Token) (*pb.RoleRsp, error) { - account := utils.ParseToken(in.Token) - if account == nil { - return nil, fmt.Errorf("token is error") - } - utils.Sugar.Debugf("login account: %v", account) - ok, role := models.RoleExistByUid(account.Uid) +func (s *GameServer) LoginHandler(ctx context.Context, in *pb.LoginReq) (*pb.RoleRsp, error) { + ok, role := models.RoleExistByUid(in.Uid) if !ok { return &pb.RoleRsp{ - Rsp: &pb.PubRsp{ - Code: 1, - Msg: "role not exist", - }, - + Code: 1, }, nil } return &pb.RoleRsp{ - Rsp: &pb.PubRsp{ - Code: 0, - Msg: "successful", - }, + Code: 0, Role: role.Role, Hero: models.GetHeros(role.Heros), }, nil diff --git a/actions/server.go b/actions/server.go index 59b1de3..3d362b2 100644 --- a/actions/server.go +++ b/actions/server.go @@ -2,6 +2,7 @@ package actions import ( "context" + "fmt" "google.golang.org/grpc" "google.golang.org/grpc/reflection" "pro2d/conf" @@ -10,13 +11,13 @@ import ( "pro2d/utils" ) -type AccountServer struct{ - pb.UnimplementedAccountServer +type LoginServer struct{ + pb.UnsafeLoginServer *BasicServer } -func NewAccountServer() *AccountServer { - return &AccountServer{ +func NewAccountServer() *LoginServer { + return &LoginServer{ BasicServer: NewServer(), } } @@ -30,7 +31,7 @@ func AccountServerInterceptor(ctx context.Context, req interface{}, info *grpc.U return resp, err } -func (s *AccountServer)Start() error { +func (s *LoginServer)Start() error { lis, err := s.BasicServer.Start(conf.GlobalConf.AccountConf) if err != nil { return err @@ -41,17 +42,17 @@ func (s *AccountServer)Start() error { //new一个grpc s.GrpcServer = grpc.NewServer(grpc.UnaryInterceptor(AccountServerInterceptor)) - pb.RegisterAccountServer(s.GrpcServer, s) + pb.RegisterLoginServer(s.GrpcServer, s) reflection.Register(s.GrpcServer) //在给定的gRPC服务器上注册服务器反射服务 // Serve方法在lis上接受传入连接,为每个连接创建一个ServerTransport和server的goroutine。 // 该goroutine读取gRPC请求,然后调用已注册的处理程序来响应它们。 - utils.Sugar.Debugf("Start AccountServer listening on %d", conf.GlobalConf.AccountConf.Port) + utils.Sugar.Debugf("Start LoginServer listening on %d", conf.GlobalConf.AccountConf.Port) return s.GrpcServer.Serve(lis) } -func (s *AccountServer)Stop() { +func (s *LoginServer)Stop() { s.BasicServer.Stop() } @@ -69,7 +70,12 @@ func NewGameServer() *GameServer { func GameServerInterceptor(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) { - utils.Sugar.Debugf("gRPC method: %s, %v", info.FullMethod, req) + //utils.Sugar.Debugf("gRPC method: %s, %v", info.FullMethod, req) + acc := utils.CheckAuth(ctx) + if acc == nil { + return nil, fmt.Errorf("token error") + } + resp, err := handler(ctx, req) return resp, err } diff --git a/go.mod b/go.mod index 454f711..9c329d4 100644 --- a/go.mod +++ b/go.mod @@ -5,6 +5,7 @@ go 1.17 require ( github.com/dgrijalva/jwt-go v3.2.0+incompatible github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b + go.etcd.io/etcd/api/v3 v3.5.2 go.etcd.io/etcd/client/v3 v3.5.2 go.mongodb.org/mongo-driver v1.8.3 go.uber.org/zap v1.17.0 @@ -27,7 +28,6 @@ require ( github.com/xdg-go/scram v1.0.2 // indirect github.com/xdg-go/stringprep v1.0.2 // indirect github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect - go.etcd.io/etcd/api/v3 v3.5.2 // indirect go.etcd.io/etcd/client/pkg/v3 v3.5.2 // indirect go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect diff --git a/models/account.go b/models/account.go index 0ac3142..027c1ff 100644 --- a/models/account.go +++ b/models/account.go @@ -7,7 +7,7 @@ import ( type AccountModel struct { *db.MgoColl - *pb.AccountInfo + *pb.Account } func AccountExistByPhone(phone string) (bool, *AccountModel){ @@ -19,12 +19,12 @@ func AccountExistByPhone(phone string) (bool, *AccountModel){ } func NewAccount(phone string) *AccountModel { - ac := &pb.AccountInfo{ + ac := &pb.Account{ Phone: phone, } account := &AccountModel{ MgoColl: db.NewMongoColl(phone, ac), - AccountInfo: ac, + Account: ac, } return account diff --git a/models/init.go b/models/init.go index a01abd2..db72f6b 100644 --- a/models/init.go +++ b/models/init.go @@ -24,7 +24,7 @@ func InitDoc(schema ...interface{}) { func InitAccountServerModels() { var schema []interface{} = []interface{}{ - pb.AccountInfo{}, + pb.Account{}, } InitDoc(schema...) } diff --git a/test/client.go b/test/client.go index b73cd72..58878ab 100644 --- a/test/client.go +++ b/test/client.go @@ -9,7 +9,7 @@ import ( "pro2d/utils" ) -func Register(c pb.AccountClient, phone, password string) error { +func Register(c pb.LoginClient, phone, password string) error { r, err := c.RegisterHandler(context.Background(), &pb.Register{ Phone: "17683852936", Password: "123456", @@ -20,14 +20,17 @@ func Register(c pb.AccountClient, phone, password string) error { return err } if r.Code != 0 { - return fmt.Errorf("%s", r.Msg) + return fmt.Errorf("register fail") } utils.Sugar.Debug("register success") return nil } -func Login(loginUri, token string) { - gameConn, err := grpc.Dial(loginUri, grpc.WithInsecure() ) +func Login(loginUri, token, uid string) { + var opts []grpc.DialOption + // 指定自定义认证 + opts = append(opts, grpc.WithPerRPCCredentials(&utils.AuthToken{Token: token}), grpc.WithInsecure()) + gameConn, err := grpc.Dial(loginUri, opts...) if err != nil { utils.Sugar.Errorf("game conn err: %v", err) return @@ -36,8 +39,9 @@ func Login(loginUri, token string) { client:= pb.NewGameClient(gameConn) var role *pb.Role - loginRsp, err := client.LoginHandler(context.Background(), &pb.Token{ - Token: token, + loginRsp, err := client.LoginHandler(context.Background(), &pb.LoginReq{ + Uid: uid, + Device: "111111", }) if err != nil { @@ -46,14 +50,14 @@ func Login(loginUri, token string) { } role = loginRsp.Role - if loginRsp.Rsp.Code != 0 { - utils.Sugar.Debugf("login rsp: %v", loginRsp.Rsp.Msg) - createRole, err := client.CreateRoleHandler(context.Background(), &pb.Token{Token: token}) + if loginRsp.Code != 0 { + utils.Sugar.Debugf("login fail, role not exist") + createRole, err := client.CreateRoleHandler(context.Background(), &pb.LoginReq{Uid: uid, Device: "11111"}) if err != nil { utils.Sugar.Errorf("create role err: %v", err) return } - utils.Sugar.Debug("create role rsp: ", createRole.Rsp.Code, createRole.Rsp.Msg) + utils.Sugar.Debug("create role rsp: ", createRole.Code) role = createRole.Role } @@ -67,13 +71,13 @@ func main() { return } defer conn.Close() - c := pb.NewAccountClient(conn) - //err = Register(c,"17683852936", "123456") + c := pb.NewLoginClient(conn) + err = Register(c,"17683852936", "123456") //if err != nil { // utils.Sugar.Errorf("register err: %v", err) // return //} - rsp, err := c.CreateTokenHandler(context.Background(), &pb.AccountInfo{ + rsp, err := c.CreateTokenHandler(context.Background(), &pb.Account{ Phone: "17683852936", Password: "123456", }) @@ -83,12 +87,12 @@ func main() { return } - if rsp.Rsp.Code != 0 { - utils.Sugar.Errorf("createtoken err: %v", rsp.Rsp.Msg) + if rsp.Code != 0 { + utils.Sugar.Errorf("createtoken err" ) return } if len(rsp.GameService) >0 { - Login(rsp.GameService[0].Address, rsp.Token) + Login(rsp.GameService[0].Address, rsp.Token, rsp.Uid) } } diff --git a/utils/jwt.go b/utils/jwt.go index aa56471..0f69e83 100644 --- a/utils/jwt.go +++ b/utils/jwt.go @@ -10,7 +10,7 @@ import ( "google.golang.org/grpc/metadata" ) -func CreateToken(account *pb.AccountInfo) (tokenString string) { +func CreateToken(account *pb.Account) (tokenString string) { token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{ "iss": "pro2d-app-server", "aud": "pro2d-app-server", @@ -19,7 +19,6 @@ func CreateToken(account *pb.AccountInfo) (tokenString string) { "sub": "pro2d", "phone": account.Phone, "uid": account.Uid, - "device": account.Device, }) tokenString, err := token.SignedString([]byte(Pro2DTokenSignedString)) if err != nil { @@ -28,7 +27,7 @@ func CreateToken(account *pb.AccountInfo) (tokenString string) { return tokenString } -func ParseToken(tokenStr string)*pb.AccountInfo { +func ParseToken(tokenStr string)*pb.Account{ var clientClaims Claims token, err := jwt.ParseWithClaims(tokenStr, &clientClaims, func(token *jwt.Token) (interface{}, error) { if token.Header["alg"] != "HS256" { @@ -47,23 +46,9 @@ func ParseToken(tokenStr string)*pb.AccountInfo { Sugar.Error("ErrInvalidToken") return nil } - return &clientClaims.AccountInfo + return &clientClaims.Account } -// AuthToken 自定义认证 -type AuthToken struct { - Token string -} - -func (c AuthToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { - return map[string]string{ - "authorization": c.Token, - }, nil -} - -func (c AuthToken) RequireTransportSecurity() bool { - return false -} // Claims defines the struct containing the token claims. type Claims struct { @@ -71,7 +56,7 @@ type Claims struct { //phone string `json:"phone"` //uid int64 `json:"uid"` //device string `json:"device"` - pb.AccountInfo + pb.Account } // 从 context 的 metadata 中,取出 token @@ -89,10 +74,26 @@ func getTokenFromContext(ctx context.Context) (string, error) { return token[0], nil } -func CheckAuth(ctx context.Context) *pb.AccountInfo { +func CheckAuth(ctx context.Context) *pb.Account{ tokenStr, err := getTokenFromContext(ctx) if err != nil { - panic("get token from context error") + Sugar.Errorf("get token from context error") + return nil } return ParseToken(tokenStr) +} + +// AuthToken 自定义认证 客户端使用 +type AuthToken struct { + Token string +} + +func (c AuthToken) GetRequestMetadata(ctx context.Context, uri ...string) (map[string]string, error) { + return map[string]string{ + "authorization": c.Token, + }, nil +} + +func (c AuthToken) RequireTransportSecurity() bool { + return false } \ No newline at end of file diff --git a/utils/jwt_test.go b/utils/jwt_test.go index 55e809c..e947f4d 100644 --- a/utils/jwt_test.go +++ b/utils/jwt_test.go @@ -7,11 +7,10 @@ import ( ) func TestCreateToken(t *testing.T) { - account := &pb.AccountInfo{ + account := &pb.Account{ Phone: "17683852936", Password: "123456", - Uid: 12312, - Device: "12312312", + Uid: "12312", } token := CreateToken(account) ac := ParseToken(token) -- libgit2 0.21.2