add token
This commit is contained in:
parent
524e310dfe
commit
3d71936ecf
|
@ -28,7 +28,7 @@ func New(secret string) {
|
||||||
|
|
||||||
func GenerateTokenAes(id uint, identity, client, role string, owner any, extend map[string]string) (string, error) {
|
func GenerateTokenAes(id uint, identity, client, role string, owner any, extend map[string]string) (string, error) {
|
||||||
if !(JwtSecretLen == 16 || JwtSecretLen == 24 || JwtSecretLen == 32) {
|
if !(JwtSecretLen == 16 || JwtSecretLen == 24 || JwtSecretLen == 32) {
|
||||||
return "", errcode.ErrJWTSecretKey
|
return "", errcode.ErrTokenSecretKey
|
||||||
}
|
}
|
||||||
expireTime := time.Now().Add(vars.JwtExpire)
|
expireTime := time.Now().Add(vars.JwtExpire)
|
||||||
claims := types.JwtClaims{
|
claims := types.JwtClaims{
|
||||||
|
@ -43,7 +43,7 @@ func GenerateTokenAes(id uint, identity, client, role string, owner any, extend
|
||||||
|
|
||||||
byte, err := json.Marshal(claims)
|
byte, err := json.Marshal(claims)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errcode.ErrJWTJsonEncode
|
return "", errcode.ErrTokenJsonEncode
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := AesEncryptCBC(byte)
|
token, err := AesEncryptCBC(byte)
|
||||||
|
@ -59,7 +59,7 @@ func AesEncryptCBC(plan []byte) (string, error) {
|
||||||
// NewCipher该函数限制了输入k的长度必须为16, 24或者32
|
// NewCipher该函数限制了输入k的长度必须为16, 24或者32
|
||||||
block, err := aes.NewCipher(JwtSecret)
|
block, err := aes.NewCipher(JwtSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", errcode.ErrJWTSecretKey
|
return "", errcode.ErrTokenSecretKey
|
||||||
}
|
}
|
||||||
// 获取秘钥块的长度
|
// 获取秘钥块的长度
|
||||||
blockSize := block.BlockSize()
|
blockSize := block.BlockSize()
|
||||||
|
@ -76,17 +76,17 @@ func AesEncryptCBC(plan []byte) (string, error) {
|
||||||
|
|
||||||
func AesDecryptCBC(cryted string) (b []byte, err error) {
|
func AesDecryptCBC(cryted string) (b []byte, err error) {
|
||||||
if (JwtSecretLen == 16 || JwtSecretLen == 24 || JwtSecretLen == 32) == false {
|
if (JwtSecretLen == 16 || JwtSecretLen == 24 || JwtSecretLen == 32) == false {
|
||||||
return nil, errcode.ErrJWTSecretKey
|
return nil, errcode.ErrTokenSecretKey
|
||||||
}
|
}
|
||||||
// 转成字节数组
|
// 转成字节数组
|
||||||
crytedByte, err := base64.StdEncoding.DecodeString(cryted)
|
crytedByte, err := base64.StdEncoding.DecodeString(cryted)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errcode.ErrJWTBase64Decode
|
return nil, errcode.ErrTokenBase64Decode
|
||||||
}
|
}
|
||||||
// 分组秘钥
|
// 分组秘钥
|
||||||
block, err := aes.NewCipher(JwtSecret)
|
block, err := aes.NewCipher(JwtSecret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errcode.ErrJWTSecretKey
|
return nil, errcode.ErrTokenSecretKey
|
||||||
}
|
}
|
||||||
// 获取秘钥块的长度
|
// 获取秘钥块的长度
|
||||||
blockSize := block.BlockSize()
|
blockSize := block.BlockSize()
|
||||||
|
@ -99,7 +99,7 @@ func AesDecryptCBC(cryted string) (b []byte, err error) {
|
||||||
// 去补全码
|
// 去补全码
|
||||||
orig = PKCS7UnPadding(orig, blockSize)
|
orig = PKCS7UnPadding(orig, blockSize)
|
||||||
if orig == nil {
|
if orig == nil {
|
||||||
return nil, errcode.ErrJWTAuthParseFail
|
return nil, errcode.ErrTokenAuthParseFail
|
||||||
}
|
}
|
||||||
return orig, nil
|
return orig, nil
|
||||||
}
|
}
|
||||||
|
@ -152,12 +152,12 @@ func ParseTokenAes(token string) (*types.JwtClaims, error) {
|
||||||
var ac *types.JwtClaims
|
var ac *types.JwtClaims
|
||||||
err = json.Unmarshal(data, &ac)
|
err = json.Unmarshal(data, &ac)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errcode.ErrJWTAuthParseFail
|
return nil, errcode.ErrTokenAuthParseFail
|
||||||
}
|
}
|
||||||
|
|
||||||
expireTime := time.Now().Unix()
|
expireTime := time.Now().Unix()
|
||||||
if expireTime > ac.ExpiresAt {
|
if expireTime > ac.ExpiresAt {
|
||||||
return nil, errcode.ErrJWTAuthExpire
|
return nil, errcode.ErrTokenAuthExpire
|
||||||
}
|
}
|
||||||
|
|
||||||
return ac, nil
|
return ac, nil
|
||||||
|
|
|
@ -0,0 +1,95 @@
|
||||||
|
package token
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"encoding/json"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"git.apinb.com/bsm-sdk/core/errcode"
|
||||||
|
"git.apinb.com/bsm-sdk/core/vars"
|
||||||
|
"github.com/golang-jwt/jwt/v5"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Claims struct {
|
||||||
|
ID uint `json:"id"`
|
||||||
|
Identity string `json:"identity"`
|
||||||
|
Extend map[string]string `json:"extend"`
|
||||||
|
Client string `json:"client"`
|
||||||
|
Owner any `json:"owner"`
|
||||||
|
Role string `json:"role"`
|
||||||
|
jwt.RegisteredClaims // v5版本新加的方法
|
||||||
|
}
|
||||||
|
|
||||||
|
type tokenJwt struct {
|
||||||
|
SecretKey string
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(secretKey string) *tokenJwt {
|
||||||
|
return &tokenJwt{SecretKey: secretKey}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 生成JWT
|
||||||
|
func (t *tokenJwt) GenerateJwt(id uint, identity, client, role string, owner any, extend map[string]string) (string, error) {
|
||||||
|
keyLen := len(t.SecretKey)
|
||||||
|
if !(keyLen == 16 || keyLen == 24 || keyLen == 32) {
|
||||||
|
return "", errcode.ErrTokenSecretKey
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now()
|
||||||
|
|
||||||
|
claims := Claims{
|
||||||
|
ID: id,
|
||||||
|
Identity: identity,
|
||||||
|
Client: client,
|
||||||
|
Extend: extend,
|
||||||
|
Owner: owner,
|
||||||
|
Role: role,
|
||||||
|
RegisteredClaims: jwt.RegisteredClaims{
|
||||||
|
ExpiresAt: jwt.NewNumericDate(now.Add(vars.JwtExpire)), // 过期时间24小时
|
||||||
|
IssuedAt: jwt.NewNumericDate(now), // 签发时间
|
||||||
|
NotBefore: jwt.NewNumericDate(now), // 生效时间
|
||||||
|
},
|
||||||
|
}
|
||||||
|
// 使用HS256签名算法
|
||||||
|
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||||
|
s, err := token.SignedString([]byte(t.SecretKey))
|
||||||
|
return s, errcode.String(errcode.ErrTokenGenerate, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析JWT
|
||||||
|
func (t *tokenJwt) ParseJwt(tokenstring string) (*Claims, error) {
|
||||||
|
token, err := jwt.ParseWithClaims(tokenstring, &Claims{}, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte(t.SecretKey), nil
|
||||||
|
})
|
||||||
|
if claims, ok := token.Claims.(*Claims); ok && token.Valid {
|
||||||
|
return claims, nil
|
||||||
|
} else {
|
||||||
|
return nil, errcode.String(errcode.ErrTokenParse, err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证JWT是否过期
|
||||||
|
func (t *tokenJwt) IsExpired(tokenstring string) (bool, error) {
|
||||||
|
// 分割JWT的三个部分
|
||||||
|
parts := strings.Split(tokenstring, ".")
|
||||||
|
if len(parts) != 3 {
|
||||||
|
return false, errcode.ErrTokenDataInvalid
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解码Payload部分
|
||||||
|
payload, err := base64.RawURLEncoding.DecodeString(parts[1])
|
||||||
|
if err != nil {
|
||||||
|
return false, errcode.String(errcode.ErrTokenBase64Decode, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析JSON
|
||||||
|
var claims jwt.RegisteredClaims
|
||||||
|
if err := json.Unmarshal(payload, &claims); err != nil {
|
||||||
|
return false, errcode.String(errcode.ErrTokenJsonDecode, err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查过期时间
|
||||||
|
currentTime := time.Now().Unix()
|
||||||
|
return claims.ExpiresAt.Unix() < currentTime, nil
|
||||||
|
}
|
|
@ -3,8 +3,6 @@
|
||||||
package errcode
|
package errcode
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"strings"
|
|
||||||
|
|
||||||
"google.golang.org/grpc/codes"
|
"google.golang.org/grpc/codes"
|
||||||
"google.golang.org/grpc/status"
|
"google.golang.org/grpc/status"
|
||||||
)
|
)
|
||||||
|
@ -33,18 +31,22 @@ var (
|
||||||
ErrRecordNotFound = NewError(1112, "Record Not Found") // 记录未找到
|
ErrRecordNotFound = NewError(1112, "Record Not Found") // 记录未找到
|
||||||
)
|
)
|
||||||
|
|
||||||
// JWT认证相关错误码,起始码:1300
|
// Token认证相关错误码,起始码:1300
|
||||||
var (
|
var (
|
||||||
ErrJWTAuthNotFound = NewError(1301, "JWT Authorization Not Found") // JWT授权未找到
|
ErrTokenAuthNotFound = NewError(1301, "Token Authorization Not Found") // Token授权未找到
|
||||||
ErrJWTBase64Decode = NewError(1302, "JWT Authorization Base64 Decode Error") // JWT Base64解码错误
|
ErrTokenDataInvalid = NewError(1302, "Token Authorization Data Invalid") // Token授权数据无效
|
||||||
ErrJWTAuthParseFail = NewError(1303, "JWT Authorization Fail") // JWT授权解析失败
|
ErrTokenBase64Decode = NewError(1303, "Token Authorization Base64 Decode Error") // Token Base64解码错误
|
||||||
ErrJWTAuthKeyId = NewError(1304, "JWT Key:Id Incorrect") // JWT密钥ID错误
|
ErrTokenAuthParseFail = NewError(1304, "Token Authorization Fail") // Token授权解析失败
|
||||||
ErrJWTAuthKeyIdentity = NewError(1305, "JWT Key:Identity Incorrect") // JWT密钥身份错误
|
ErrTokenAuthKeyId = NewError(1305, "Token Key:Id Incorrect") // Token密钥ID错误
|
||||||
ErrJWTAuthTokenChanged = NewError(1306, "JWT Authorization Changed") // JWT授权已变更
|
ErrTokenAuthKeyIdentity = NewError(1306, "Token Key:Identity Incorrect") // Token密钥身份错误
|
||||||
ErrJWTAuthExpire = NewError(1307, "JWT Authorization Expire") // JWT授权已过期
|
ErrTokenAuthTokenChanged = NewError(1307, "Token Authorization Changed") // Token授权已变更
|
||||||
ErrJWTJsonDecode = NewError(1308, "JWT Authorization JSON Decode Error") // JWT JSON解码错误
|
ErrTokenAuthExpire = NewError(1308, "Token Authorization Expire") // Token授权已过期
|
||||||
ErrJWTJsonEncode = NewError(1309, "JWT Authorization JSON Encode Error") // JWT JSON编码错误
|
ErrTokenJsonDecode = NewError(1309, "Token Authorization JSON Decode Error") // Token JSON解码错误
|
||||||
ErrJWTSecretKey = NewError(1310, "JWT SecretKey Error") // JWT密钥错误
|
ErrTokenJsonEncode = NewError(1310, "Token Authorization JSON Encode Error") // Token JSON编码错误
|
||||||
|
ErrTokenSecretKey = NewError(1311, "Token SecretKey Error") // Token密钥错误
|
||||||
|
ErrTokenSecretKeyNotFound = NewError(1312, "Token SecretKey Not Found") // Token密钥未找到
|
||||||
|
ErrTokenGenerate = NewError(1313, "Generate Token Fail") // 生成令牌失败
|
||||||
|
ErrTokenParse = NewError(1314, "Parse Token Fail") // 解析令牌失败
|
||||||
)
|
)
|
||||||
|
|
||||||
// 基础设施相关错误码,起始码:1500
|
// 基础设施相关错误码,起始码:1500
|
||||||
|
@ -98,6 +100,15 @@ func ErrFatal(code int, msg string) error {
|
||||||
// code: 错误码
|
// code: 错误码
|
||||||
// msg: 错误消息,会自动转换为大写
|
// msg: 错误消息,会自动转换为大写
|
||||||
func ErrNotFound(code int, msg string) error {
|
func ErrNotFound(code int, msg string) error {
|
||||||
AllErrors[code] = strings.ToUpper(msg)
|
AllErrors[code] = msg
|
||||||
return status.New(codes.Code(code), strings.ToUpper(msg)).Err()
|
return status.New(codes.Code(code), msg).Err()
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsErr 检查错误是否与指定的错误匹配
|
||||||
|
func IsErr(err, target error) bool {
|
||||||
|
return status.Code(err) == status.Code(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
func String(err error, msg string) error {
|
||||||
|
return status.New(status.Code(err), err.Error()+", "+msg).Err()
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,8 +60,8 @@ func JwtAuth(time_verify bool) gin.HandlerFunc {
|
||||||
func ParseAuth(c *gin.Context) (*types.JwtClaims, error) {
|
func ParseAuth(c *gin.Context) (*types.JwtClaims, error) {
|
||||||
claims, ok := c.Get("Auth")
|
claims, ok := c.Get("Auth")
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Printf("获取登录信息异常: %v", errcode.ErrJWTAuthNotFound)
|
log.Printf("获取登录信息异常: %v", errcode.ErrTokenAuthNotFound)
|
||||||
return nil, errcode.ErrJWTAuthNotFound
|
return nil, errcode.ErrTokenAuthNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
json_claims, err := json.Marshal(claims)
|
json_claims, err := json.Marshal(claims)
|
||||||
|
|
|
@ -20,12 +20,12 @@ func ParseMetaCtx(ctx context.Context, opts *ParseOptions) (*types.JwtClaims, er
|
||||||
// 解析metada中的信息并验证
|
// 解析metada中的信息并验证
|
||||||
md, ok := metadata.FromIncomingContext(ctx)
|
md, ok := metadata.FromIncomingContext(ctx)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errcode.ErrJWTAuthNotFound
|
return nil, errcode.ErrTokenAuthNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
var Authorizations []string = md.Get("authorization")
|
var Authorizations []string = md.Get("authorization")
|
||||||
if len(Authorizations) == 0 || Authorizations[0] == "" {
|
if len(Authorizations) == 0 || Authorizations[0] == "" {
|
||||||
return nil, errcode.ErrJWTAuthNotFound
|
return nil, errcode.ErrTokenAuthNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
claims, err := encipher.ParseTokenAes(Authorizations[0])
|
claims, err := encipher.ParseTokenAes(Authorizations[0])
|
||||||
|
|
Loading…
Reference in New Issue