150 lines
3.8 KiB
Go
150 lines
3.8 KiB
Go
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
|
||
}
|