hpds_jkw_web/internal/middleware/jwt.go

150 lines
3.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package middleware
import (
"encoding/json"
"fmt"
"hpds-iot-web/model"
e "hpds-iot-web/pkg/err"
"net/http"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
var secretKey = []byte("17715d3df8712f0a3b31cfed384f668e95822de4e4a371e4ceaa6f1b279e482a0af32b4615d39f8857d0a1d99d2787f773147a9ed7587b243e0fe1b04076e307")
// 验签使用
var AuthKey = "auth-key"
var AuthSignature = "auth-signature"
// Claims 自定义声明
type Claims struct {
Avatar string `json:"avatar"`
Desc string `json:"desc"`
HomePath string `json:"homePath"`
RealName string `json:"realName"`
Roles []model.SystemRole `json:"roles"`
UserId int64 `json:"userId"`
Token string `json:"token,omitempty"`
Phone string `json:"phone"`
jwt.StandardClaims
}
// Sign 生成token
func Sign(user *model.SystemUser, expires int) (string, error) {
// 过期时间为秒
expAt := time.Now().Add(time.Duration(expires) * time.Second).Unix()
// 创建声明
claims := Claims{
Avatar: user.Avatar,
Desc: user.Desc,
HomePath: user.HomePath,
RealName: user.RealName,
Roles: model.GetRolesByUserId(user.UserId),
UserId: user.UserId,
Phone: user.Phone,
StandardClaims: jwt.StandardClaims{
ExpiresAt: expAt,
Issuer: "交科院",
},
}
var err error
//创建token指定加密算法为HS256
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
claims.Token, err = token.SignedString(secretKey)
//生成token
return claims.Token, err
}
// JwtAuthMiddleware JWT处理中间件
func JwtAuthMiddleware(logger *zap.Logger) gin.HandlerFunc {
return func(c *gin.Context) {
path := c.Request.URL.Path
var (
err error
Cookie *http.Cookie
usClaims *Claims
user *model.SystemUser
)
token := c.GetHeader("Authorization")
// 这里可以过滤不需要进行验证的接口
if path == "/api/user/login" || path == "/api/health" {
goto Return
}
if len(token) == 0 {
Cookie, err = c.Request.Cookie("token")
if err != nil {
logger.With(
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Any("request", c.Params),
).Error(err.Error())
goto Return
}
token = Cookie.Value
}
if len(token) <= 0 {
logger.With(
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Any("request", c.Params),
).Error("缺少token")
goto Return
}
usClaims, err = GetUserInfoByToken(c, token, logger)
if err != nil {
c.JSON(e.NoAuth, gin.H{"code": e.NoAuth, "msg": "未登录的用户请求"})
c.Abort()
return
}
if err != nil {
logger.With(
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Any("request", c.Params),
).Error(err.Error())
goto Return
}
user, err = model.GetUserById(usClaims.UserId)
if err != nil {
logger.With(
zap.String("method", c.Request.Method),
zap.String("path", path),
zap.Any("request", c.Params),
).Error(err.Error())
goto Return
}
c.Set("operatorUser", user)
Return:
if err != nil {
c.Header("Content-Type", "application/json")
c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{
"code": http.StatusBadRequest,
"status": http.StatusText(http.StatusBadRequest),
"path": path,
"message": "失败",
"error": "token过期/失效,请登录后重试",
"data": nil,
})
return
}
c.Next()
}
}
func GetUserInfoByToken(ctx *gin.Context, token string, logger *zap.Logger) (data *Claims, err error) {
nosql := NewNoSql(logger)
su, err := nosql.Get(ctx, token)
if err != nil {
return nil, err
}
data = new(Claims)
err = json.Unmarshal([]byte(fmt.Sprintf("%s", su)), data)
if err != nil {
return nil, err
}
return data, nil
}