This commit is contained in:
2025-02-06 11:14:33 +08:00
commit 07847a2d9e
535 changed files with 65131 additions and 0 deletions

View 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
}