1
This commit is contained in:
295
pkg/cryptohelper/jwthelper/jwthelper.go
Normal file
295
pkg/cryptohelper/jwthelper/jwthelper.go
Normal file
@ -0,0 +1,295 @@
|
||||
package jwthelper
|
||||
|
||||
import (
|
||||
"go-admin/common/const/rediskey"
|
||||
"go-admin/common/helper"
|
||||
"go-admin/pkg/utility"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
"go.uber.org/zap"
|
||||
|
||||
"fmt"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
log "github.com/go-admin-team/go-admin-core/logger"
|
||||
)
|
||||
|
||||
// LoginUserJwt 用户登入信息
|
||||
type LoginUserJwt struct {
|
||||
UserID int
|
||||
NickName string
|
||||
Phone string
|
||||
Email string
|
||||
OsType int
|
||||
}
|
||||
|
||||
// LoginClaims 自定义声明结构体并内嵌jwt.StandardClaims
|
||||
// jwt包自带的jwt.StandardClaims只包含了官方字段
|
||||
// 我们这里需要额外记录一个nickname字段,所以要自定义结构体
|
||||
// 如果想要保存更多信息,都可以添加到这个结构体中
|
||||
type LoginClaims struct {
|
||||
UserID int `json:"userid"`
|
||||
NickName string `json:"nickname"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// JwtSigningKey Jwt signing key
|
||||
var JwtSigningKey = []byte("tokexapp.com")
|
||||
|
||||
var LoginTokenValidTime = 48 * time.Hour // 登录验证token有效期
|
||||
var LoginAdminTokenValidTime = 24 * time.Hour
|
||||
|
||||
var TokenNotValid = -1 // Token无效
|
||||
var TokenExpire = -2 // Token过期
|
||||
var TokenSuccess = 1 // Token正常
|
||||
|
||||
// CreateJwtToken 创建用户jwt token
|
||||
func CreateJwtToken(userJwt LoginUserJwt, minute int) (string, string) {
|
||||
// 创建一个我们自己的声明
|
||||
expire := time.Now().Add(time.Minute * time.Duration(minute)) //.Unix()
|
||||
claims := LoginClaims{
|
||||
UserID: userJwt.UserID,
|
||||
Phone: userJwt.Phone,
|
||||
NickName: userJwt.NickName,
|
||||
Email: userJwt.Email,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(expire),
|
||||
Issuer: "Tokex", // 签发人
|
||||
},
|
||||
}
|
||||
|
||||
// 使用指定的签名方法创建签名对象
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
tokenStr, err := token.SignedString(JwtSigningKey)
|
||||
if err != nil {
|
||||
log.Error("获取jwt token失败:", zap.Error(err))
|
||||
return "", ""
|
||||
}
|
||||
return tokenStr, fmt.Sprintf("%v", expire.Unix())
|
||||
}
|
||||
|
||||
// MidValidToken 检验token是否有效,返回token解密后的string
|
||||
func MidValidToken(tokenStr string, source int) (int, string) {
|
||||
// 解析token
|
||||
token, err := jwt.ParseWithClaims(tokenStr, &LoginClaims{}, func(token *jwt.Token) (i interface{}, err error) {
|
||||
return JwtSigningKey, nil
|
||||
})
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "token is expired") {
|
||||
return TokenExpire, ""
|
||||
}
|
||||
// loghelper.Error("MidValidToken解析token失败", zap.Error(err))
|
||||
return TokenNotValid, ""
|
||||
}
|
||||
if !token.Valid {
|
||||
log.Error("MidValidToken解析token无效", zap.Error(err))
|
||||
return TokenNotValid, ""
|
||||
}
|
||||
claims, ok := token.Claims.(*LoginClaims)
|
||||
if !ok {
|
||||
return TokenNotValid, ""
|
||||
}
|
||||
|
||||
// 校验token
|
||||
key := fmt.Sprintf(rediskey.AppLoginUserToken, claims.UserID)
|
||||
if source == 3 {
|
||||
key = fmt.Sprintf(rediskey.PCLoginUserToken, claims.UserID)
|
||||
}
|
||||
appToken, _ := helper.DefaultRedis.GetString(key)
|
||||
if len(appToken) == 0 {
|
||||
//说明未登入或者过期
|
||||
return TokenExpire, ""
|
||||
}
|
||||
if appToken != tokenStr {
|
||||
//说明是被t
|
||||
return TokenExpire, ""
|
||||
}
|
||||
|
||||
return TokenSuccess, strings.Join([]string{utility.IntToString(claims.UserID),
|
||||
claims.NickName, claims.Phone, claims.Email}, ",")
|
||||
}
|
||||
|
||||
// GetLoginUserJwt 解析用户登入信息
|
||||
func GetLoginUserJwt(tokenStr string) LoginUserJwt {
|
||||
if len(tokenStr) == 0 {
|
||||
return LoginUserJwt{}
|
||||
}
|
||||
tokenArr := strings.Split(tokenStr, ",")
|
||||
arrLen := len(tokenArr)
|
||||
item := LoginUserJwt{
|
||||
UserID: utility.StringAsInteger(tokenArr[0]),
|
||||
}
|
||||
if arrLen > 1 {
|
||||
item.NickName = tokenArr[1]
|
||||
}
|
||||
if arrLen > 2 {
|
||||
item.Phone = tokenArr[2]
|
||||
}
|
||||
if arrLen > 3 {
|
||||
item.Email = tokenArr[3]
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// AgentLoginJwt ==============Agent 代理商 JWT========================//
|
||||
type AgentLoginJwt struct {
|
||||
AgentId int `json:"agent_id"` // 代理商ID
|
||||
UserId int `json:"user_id"` // 代理商关联的用户ID
|
||||
Name string `json:"name"` // 代理商姓名
|
||||
Email string `json:"email"` // 代理商邮件
|
||||
IP string `json:"ip"` // 代理商IP
|
||||
}
|
||||
type AgentLoginClaims struct {
|
||||
AgentId int `json:"agent_id"` // 代理商ID
|
||||
UserId int `json:"user_id"` // 代理商关联的用户ID
|
||||
Name string `json:"name"` // 代理商姓名
|
||||
Email string `json:"email"` // 代理商邮件
|
||||
IP string `json:"ip"` // 代理商IP
|
||||
jwt.RegisteredClaims //StandardClaims
|
||||
}
|
||||
|
||||
var JwtAgentSigningKey = []byte("tokexagent.com") //Jwt signing key
|
||||
|
||||
// CreateAgentJwtToken 代理商产生的token
|
||||
func CreateAgentJwtToken(userJwt AgentLoginJwt, minute int) string {
|
||||
// 创建一个我们自己的声明
|
||||
exp := time.Now().Add(time.Minute * time.Duration(minute))
|
||||
c := AgentLoginClaims{
|
||||
userJwt.AgentId,
|
||||
userJwt.UserId, // 自定义字段
|
||||
userJwt.Name,
|
||||
userJwt.Email,
|
||||
userJwt.IP,
|
||||
jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(exp), // 过期时间
|
||||
Issuer: "Tokex-Agent", // 签发人
|
||||
},
|
||||
}
|
||||
// 使用指定的签名方法创建签名对象
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, c)
|
||||
tokenStr, err := token.SignedString(JwtAgentSigningKey)
|
||||
if err != nil {
|
||||
log.Error("获取jwt token失败:", zap.Error(err))
|
||||
return ""
|
||||
}
|
||||
return tokenStr
|
||||
}
|
||||
|
||||
// MidValidAgentToken 检验token是否有效,返回token解密后的string
|
||||
func MidValidAgentToken(tokenStr string) (int, string) {
|
||||
// 解析token
|
||||
token, err := jwt.ParseWithClaims(tokenStr, &AgentLoginClaims{}, func(token *jwt.Token) (i interface{}, err error) {
|
||||
return JwtAgentSigningKey, nil
|
||||
})
|
||||
if err != nil {
|
||||
return TokenNotValid, ""
|
||||
}
|
||||
if !token.Valid {
|
||||
log.Error("MidValidAgentToken解析token无效", zap.Error(err))
|
||||
return TokenNotValid, ""
|
||||
}
|
||||
claims, ok := token.Claims.(*AgentLoginClaims)
|
||||
if !ok {
|
||||
return TokenNotValid, ""
|
||||
}
|
||||
|
||||
// 校验token
|
||||
key := fmt.Sprintf(rediskey.AgentLoginUserToken, claims.AgentId)
|
||||
appToken, _ := helper.DefaultRedis.GetString(key)
|
||||
if len(appToken) == 0 {
|
||||
return TokenExpire, ""
|
||||
}
|
||||
if appToken != tokenStr {
|
||||
return TokenExpire, ""
|
||||
}
|
||||
|
||||
return TokenSuccess, strings.Join([]string{utility.IntToString(claims.AgentId), utility.IntToString(claims.UserId),
|
||||
claims.Name, claims.Email, claims.IP}, ",")
|
||||
}
|
||||
|
||||
// GetLoginAgentJwt 解析代理商登入信息
|
||||
func GetLoginAgentJwt(tokenStr string) AgentLoginJwt {
|
||||
if len(tokenStr) == 0 {
|
||||
return AgentLoginJwt{}
|
||||
}
|
||||
tokenArr := strings.Split(tokenStr, ",")
|
||||
arrLen := len(tokenArr)
|
||||
item := AgentLoginJwt{
|
||||
AgentId: utility.StringAsInteger(tokenArr[0]),
|
||||
}
|
||||
if arrLen > 1 {
|
||||
item.UserId = utility.StringAsInteger(tokenArr[1])
|
||||
}
|
||||
if arrLen > 2 {
|
||||
item.Name = tokenArr[2]
|
||||
}
|
||||
if arrLen > 3 {
|
||||
item.Email = tokenArr[3]
|
||||
}
|
||||
if arrLen > 4 {
|
||||
item.IP = tokenArr[4]
|
||||
}
|
||||
return item
|
||||
}
|
||||
|
||||
// ========== Admin 专用 JWT ========== //
|
||||
|
||||
type AdminLogin struct {
|
||||
UserID int `json:"user_id"`
|
||||
Account string `json:"account"`
|
||||
NickName string `json:"nickname"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
IP string `json:"ip"`
|
||||
}
|
||||
|
||||
type AdminLoginClaims struct {
|
||||
AdminLogin
|
||||
jwt.RegisteredClaims //StandardClaims
|
||||
}
|
||||
|
||||
var AdminSignedKey = []byte("adm23inTOKexKey:237") // Admin 签名 Key
|
||||
|
||||
const AdminTokenIssue = "tokexAdmin" // Admin 签发人
|
||||
|
||||
// GenerateAdminLoginToken 生成管理员登录 Token
|
||||
func GenerateAdminLoginToken(admin AdminLogin, expires time.Duration) string {
|
||||
exp := time.Now().Add(expires)
|
||||
claims := AdminLoginClaims{
|
||||
admin,
|
||||
jwt.RegisteredClaims{
|
||||
ExpiresAt: jwt.NewNumericDate(exp), // 过期时间
|
||||
Issuer: AdminTokenIssue, // 签发人
|
||||
},
|
||||
}
|
||||
|
||||
// 使用指定的签名方法创建签名对象
|
||||
jwtToken, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).SignedString(AdminSignedKey)
|
||||
if err != nil {
|
||||
log.Error("获取 jwtToken 失败:", zap.Error(err))
|
||||
}
|
||||
|
||||
return jwtToken
|
||||
}
|
||||
|
||||
// ParseAdminLoginToken 解析管理员登录 Token
|
||||
func ParseAdminLoginToken(jwtToken string) (pass bool, adminLogin AdminLoginClaims) {
|
||||
// 解析 jwtToken
|
||||
token, err := jwt.ParseWithClaims(jwtToken, &AdminLoginClaims{}, func(token *jwt.Token) (i interface{}, err error) {
|
||||
return AdminSignedKey, nil
|
||||
})
|
||||
if err != nil {
|
||||
log.Error("解析 jwtToken 失败:", zap.Error(err))
|
||||
return false, adminLogin
|
||||
}
|
||||
|
||||
// 判断是否验证通过,并将 Claims => AdminLoginClaims
|
||||
if claims, pass := token.Claims.(*AdminLoginClaims); pass && token.Valid {
|
||||
return pass, *claims
|
||||
}
|
||||
|
||||
return false, adminLogin
|
||||
}
|
||||
Reference in New Issue
Block a user