package http_handler import ( "context" "fmt" "git.hlsq.asia/mmorpg/service-common/db/redis" "git.hlsq.asia/mmorpg/service-common/log" "git.hlsq.asia/mmorpg/service-common/net/grpc/service" "git.hlsq.asia/mmorpg/service-common/net/http/http_resp" "git.hlsq.asia/mmorpg/service-common/proto/ss/grpc_pb" "git.hlsq.asia/mmorpg/service-common/utils" "git.hlsq.asia/mmorpg/service-gateway/config" "git.hlsq.asia/mmorpg/service-gateway/internal/global" "github.com/gin-gonic/gin" "time" ) // 这个模块处理用户登录 type LoginReq struct { Phone string `json:"phone" binding:"required,min=1"` Code string `json:"code" binding:"required,min=1"` } type LoginResp struct { USN int64 `json:"usn"` Name string `json:"name"` AccessToken string `json:"accessToken"` RefreshToken string `json:"refreshToken"` } func Login(c *gin.Context) { req := &LoginReq{} if err := c.ShouldBindJSON(req); err != nil { http_resp.JsonBadRequest(c) return } client, err := service.UserNewClientLB() if err != nil { log.Errorf("Login UserNewClientLB error: %v", err) http_resp.JsonOK(c, http_resp.Error(http_resp.Failed)) return } login, err := client.Login(c, &grpc_pb.LoginReq{ Phone: req.Phone, Code: req.Code, }) if err != nil { log.Errorf("Login Login error: %v", err) http_resp.JsonOK(c, http_resp.Error(http_resp.Failed)) return } at, rt, err := genToken(c, login.USN) http_resp.JsonOK(c, http_resp.Success(&LoginResp{ USN: login.USN, Name: login.Name, AccessToken: at, RefreshToken: rt, })) } type RefreshTokenReq struct { RefreshToken string `json:"refreshToken" binding:"required,min=1"` } type RefreshTokenResp struct { AccessToken string `json:"accessToken"` RefreshToken string `json:"refreshToken"` } func RefreshToken(c *gin.Context) { req := &RefreshTokenReq{} if err := c.ShouldBindJSON(req); err != nil { http_resp.JsonBadRequest(c) return } claims, err := utils.ParseToken(req.RefreshToken, config.Get().Auth.Secret) if err != nil { http_resp.JsonOK(c, http_resp.Error(http_resp.TokenInvalid)) return } if redis.GetClient().Get(c, fmt.Sprintf(global.KeyGatewayRefreshToken, claims.USN)).Val() != req.RefreshToken { http_resp.JsonOK(c, http_resp.Error(http_resp.TokenInvalid)) return } at, rt, err := genToken(c, claims.USN) if err != nil { log.Errorf("RefreshToken genToken error: %v, usn: %v", err, claims.USN) http_resp.JsonOK(c, http_resp.Error(http_resp.Failed)) return } http_resp.JsonOK(c, http_resp.Success(&RefreshTokenResp{ AccessToken: at, RefreshToken: rt, })) } func genToken(ctx context.Context, usn int64) (string, string, error) { at, err := genTokenOne(ctx, global.KeyGatewayAccessToken, usn, 2*time.Hour) if err != nil { return "", "", err } rt, err := genTokenOne(ctx, global.KeyGatewayRefreshToken, usn, 3*24*time.Hour) if err != nil { return "", "", err } return at, rt, nil } func genTokenOne(ctx context.Context, key string, usn int64, ttl time.Duration) (string, error) { token, err := utils.GenToken(usn, config.Get().Auth.Secret, time.Duration(config.Get().Auth.Expire)*time.Second) if err != nil { return "", err } redis.GetClient().Set(ctx, fmt.Sprintf(key, usn), token, ttl) return token, err }