hpds_jkw_web/internal/middleware/jwt.go

150 lines
3.8 KiB
Go
Raw Normal View History

2023-01-06 10:09:23 +08:00
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("token")
// 这里可以过滤不需要进行验证的接口
if path == "/user/login" || path == "/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
}