123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 |
- package middleware
- import (
- "Cold_Logistic/internal/pkg/common/codex"
- "Cold_Logistic/internal/pkg/common/constant"
- "Cold_Logistic/internal/pkg/utils/headutil"
- "Cold_Logistic/internal/server/domain/domainservice"
- "github.com/gin-gonic/gin"
- "github.com/golang-jwt/jwt/v4"
- "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/core"
- "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/errors"
- "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/log"
- "gogs.baozhida.cn/Cold_Logistic_libs/pkg/contrib/util/authutil"
- "time"
- )
- func Auth() gin.HandlerFunc {
- return func(c *gin.Context) {
- tokenType, token, err := headutil.ParseAuthHead(c)
- if err != nil {
- core.WriteResponse(c, errors.WithCodeOnce(err, codex.ErrInvalidAuthHeader, err.Error()), nil)
- c.Abort()
- return
- }
- switch tokenType {
- case constant.AuthTokenTypeBearer:
- var jwtClaim *jwt.MapClaims
- jwtClaim, err = authutil.ParseToken(token, "")
- if err != nil {
- core.WriteResponse(c, errors.WrapC(err, codex.ErrSignatureInvalid, "Parse Authorization token fail."), nil)
- c.Abort()
- return
- }
- var accountId int
- accountId, err = verifyToken(c, token, jwtClaim)
- if err != nil {
- core.WriteResponse(c, errors.WrapC(err, codex.ErrSignatureInvalid, "Parse Authorization token fail."), nil)
- c.Abort()
- return
- }
- if c.FullPath() != "/clodLogistic/app/api/v1/myself/refreshToken" {
- if !jwtClaim.VerifyExpiresAt(time.Now().Unix(), false) {
- core.WriteResponse(c, errors.WrapC(err, codex.ErrStatusForbidden, ""), nil)
- c.Abort()
- return
- }
- if err = refreshToken(c, jwtClaim); err != nil {
- core.WriteResponse(c, errors.WrapC(err, codex.ErrSignatureInvalid, "Parse Authorization token fail."), nil)
- c.Abort()
- return
- }
- }
- err = setTokenInfo(c, accountId)
- if err != nil {
- core.WriteResponse(c, errors.WrapC(err, codex.ErrSignatureInvalid, "Parse Authorization token fail."), nil)
- c.Abort()
- return
- }
- default:
- core.WriteResponse(c, errors.WithCode(codex.ErrSignatureInvalid, "unrecognized Authorization header."), nil)
- c.Abort()
- return
- }
- c.Next()
- }
- }
- func verifyToken(c *gin.Context, token string, claim *jwt.MapClaims) (int, error) {
- clMap := *claim
- _, ok := clMap["iss"].(string)
- if !ok {
- return -1, errors.New("account token iss invalid")
- }
- uid, ok := clMap["uid"].(float64)
- if !ok {
- return -1, errors.New("account token iss invalid")
- }
- accountId := int(uid)
- redisT, err := domainservice.GetToken(c, accountId)
- if err != nil {
- return -1, errors.WithStackOnce(err)
- }
- if redisT == "" {
- return -1, errors.WithCode(codex.ErrSignatureInvalid, "Parse Authorization token fail.")
- }
- if redisT != token {
- return -1, errors.New("account token iss invalid")
- }
- return accountId, nil
- }
- // refreshToken 刷新token
- func refreshToken(ctx *gin.Context, claim *jwt.MapClaims) error {
- clMap := *claim
- accId := int(clMap["uid"].(float64))
- exp := time.Now().Add(2 * time.Hour).Unix()
- expTime := time.Unix(int64(clMap["exp"].(float64)), 0)
- // 还有10分钟过期时发放新token
- if expTime.Sub(time.Now()) <= 10*time.Minute {
- newToken := authutil.Sign(accId, "", constant.CCLAppletLoginJWTISS, "", exp)
- ctx.Header("new-accessToken", newToken)
- }
- return nil
- }
- func setTokenInfo(c *gin.Context, accountId int) error {
- tokenInfo, err := domainservice.GetTokenInfoById(c, accountId)
- if err != nil {
- return errors.WithStackOnce(err)
- }
- c.Set(constant.TokenInfoKey, tokenInfo)
- // logger 补充accountId信息
- AccountIdLogger := c.Value(log.GetContextKey()).(log.Logger)
- AccountIdLogger = AccountIdLogger.WithValues("accountId", tokenInfo.AccountId)
- c.Set(log.GetContextKey(), AccountIdLogger)
- return nil
- }
|