iot_server/internal/tools/jwt/jwt.go

122 lines
3.0 KiB
Go

package jwt
import (
"fmt"
"github.com/google/uuid"
"github.com/winc-link/hummingbird/internal/pkg/constants"
"github.com/winc-link/hummingbird/internal/pkg/errort"
"github.com/winc-link/hummingbird/internal/pkg/httphelper"
"github.com/winc-link/hummingbird/internal/pkg/middleware"
"time"
"github.com/dgrijalva/jwt-go"
"github.com/gin-gonic/gin"
)
const (
JwtIssuer = "hummingbird"
tokenKey = "x-token"
)
var (
RefreshKey = "afe60362-r3f2-5e07-4d9f-g35e32650af3"
OpenAPIKey string
JwtSignKey string
)
func SetOpenAPIKey(key string) {
OpenAPIKey = key
}
func SetJwtSignKey(key string) {
JwtSignKey = key
}
func GenerateJwtSignKey() string {
return uuid.New().String()
}
//JWT 令牌认证中间件
func JWTAuth(CloseAuthToken bool) gin.HandlerFunc {
if CloseAuthToken {
return func(c *gin.Context) {}
}
return func(c *gin.Context) {
token := c.Request.Header.Get(tokenKey)
vars := c.Request.URL.Query()
if v, ok := vars[tokenKey]; ok {
token = v[0]
}
if token == "" {
httphelper.RenderFailNoLog(c, TokenInvalid, c.Writer)
c.Abort()
return
}
j := NewJWT(JwtSignKey)
claims, err := j.ParseToken(token)
if err != nil {
httphelper.RenderFailNoLog(c, TokenExpired, c.Writer)
c.Abort()
return
}
if time.Now().Unix() > claims.ExpiresAt {
httphelper.RenderFailNoLog(c, TokenExpired, c.Writer)
c.Abort()
return
}
c.Set(constants.JwtParsedInfo, claims)
c.Next()
}
}
type JWT struct {
SigningKey []byte
}
var (
TokenExpired = errort.NewCommonErr(errort.DefaultTokenPermission, fmt.Errorf("Token expired, please log in again"))
TokenNotValidYet = errort.NewCommonErr(errort.DefaultTokenPermission, fmt.Errorf("Token expired, please log in again"))
TokenMalformed = errort.NewCommonErr(errort.DefaultTokenPermission, fmt.Errorf("Token expired, please log in again"))
TokenInvalid = errort.NewCommonErr(errort.DefaultTokenPermission, fmt.Errorf("Token expired, please log in again"))
)
func NewJWT(key string) *JWT {
return &JWT{
[]byte(key),
}
}
// 创建一个token
func (j *JWT) CreateToken(claims middleware.CustomClaims) (string, error) {
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
return token.SignedString(j.SigningKey)
}
// 解析 token
func (j *JWT) ParseToken(tokenString string) (*middleware.CustomClaims, error) {
token, err := jwt.ParseWithClaims(tokenString, &middleware.CustomClaims{}, func(token *jwt.Token) (i interface{}, e error) {
return j.SigningKey, nil
})
if err != nil {
if ve, ok := err.(*jwt.ValidationError); ok {
if ve.Errors&jwt.ValidationErrorMalformed != 0 {
return nil, TokenMalformed
} else if ve.Errors&jwt.ValidationErrorExpired != 0 {
return nil, TokenExpired
} else if ve.Errors&jwt.ValidationErrorNotValidYet != 0 {
return nil, TokenNotValidYet
} else {
return nil, TokenInvalid
}
}
}
if token != nil {
if claims, ok := token.Claims.(*middleware.CustomClaims); ok && token.Valid {
return claims, nil
}
return nil, TokenInvalid
} else {
return nil, TokenInvalid
}
}