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
|
|
|
|
|
)
|
2023-01-06 16:10:18 +08:00
|
|
|
|
token := c.GetHeader("Authorization")
|
2023-01-06 10:09:23 +08:00
|
|
|
|
// 这里可以过滤不需要进行验证的接口
|
2023-04-24 15:21:17 +08:00
|
|
|
|
if path == "/api/user/login" || path == "/api/health" || path == "/api/task/event" {
|
2023-01-06 10:09:23 +08:00
|
|
|
|
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
|
|
|
|
|
}
|