122 lines
3.0 KiB
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
|
|
}
|
|
}
|