fix tempuser token general
This commit is contained in:
parent
b90ad7c5f7
commit
25ddfc9952
@ -153,7 +153,7 @@ func (l *ApplyForAgentLogic) ApplyForAgent(req *types.AgentApplyReq) (resp *type
|
|||||||
if transErr != nil {
|
if transErr != nil {
|
||||||
return nil, transErr
|
return nil, transErr
|
||||||
}
|
}
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
"tydata-server/app/main/api/internal/service"
|
"tydata-server/app/main/api/internal/service"
|
||||||
|
"tydata-server/app/main/model"
|
||||||
"tydata-server/common/ctxdata"
|
"tydata-server/common/ctxdata"
|
||||||
"tydata-server/common/xerr"
|
"tydata-server/common/xerr"
|
||||||
"tydata-server/pkg/lzkit/crypto"
|
"tydata-server/pkg/lzkit/crypto"
|
||||||
@ -124,7 +125,7 @@ func (l *QueryServiceLogic) ProcessMarriageLogic(req *types.QueryServiceReq) (*t
|
|||||||
if cacheDataErr != nil {
|
if cacheDataErr != nil {
|
||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
@ -185,7 +186,7 @@ func (l *QueryServiceLogic) ProcessHomeServiceLogic(req *types.QueryServiceReq)
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
@ -246,7 +247,7 @@ func (l *QueryServiceLogic) ProcessRiskAssessmentLogic(req *types.QueryServiceRe
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
@ -306,7 +307,7 @@ func (l *QueryServiceLogic) ProcessCompanyInfoLogic(req *types.QueryServiceReq)
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
@ -367,7 +368,7 @@ func (l *QueryServiceLogic) ProcessRentalInfoLogic(req *types.QueryServiceReq) (
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
@ -428,7 +429,7 @@ func (l *QueryServiceLogic) ProcessPreLoanBackgroundCheckLogic(req *types.QueryS
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
@ -488,7 +489,7 @@ func (l *QueryServiceLogic) ProcessBackgroundCheckLogic(req *types.QueryServiceR
|
|||||||
return nil, cacheDataErr
|
return nil, cacheDataErr
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "查询服务, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func (l *BindMobileLogic) BindMobile(req *types.BindMobileReq) (resp *types.Bind
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, 生成token失败: %+v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "绑定手机号, 生成token失败: %+v", err)
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,7 @@ func (l *DetailLogic) Detail() (resp *types.UserInfoResp, err error) {
|
|||||||
|
|
||||||
userID := claims.UserId
|
userID := claims.UserId
|
||||||
userType := claims.UserType
|
userType := claims.UserType
|
||||||
if userType == model.UserTypeTemp {
|
if userType != model.UserTypeNormal {
|
||||||
return &types.UserInfoResp{
|
return &types.UserInfoResp{
|
||||||
UserInfo: types.User{
|
UserInfo: types.User{
|
||||||
Id: userID,
|
Id: userID,
|
||||||
|
@ -29,11 +29,11 @@ func NewGetTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetToken
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error) {
|
func (l *GetTokenLogic) GetToken() (resp *types.MobileCodeLoginResp, err error) {
|
||||||
userID, err := ctxdata.GetUidFromCtx(l.ctx)
|
claims, err := ctxdata.GetClaimsFromCtx(l.ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
||||||
}
|
}
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, claims.UserId, claims.UserType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "用户信息, %v", err)
|
||||||
}
|
}
|
||||||
|
@ -64,7 +64,7 @@ func (l *MobileCodeLoginLogic) MobileCodeLogin(req *types.MobileCodeLoginReq) (r
|
|||||||
} else {
|
} else {
|
||||||
userID = user.Id
|
userID = user.Id
|
||||||
}
|
}
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, model.UserTypeNormal)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", userID)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "手机登录, 生成token失败 : %d", userID)
|
||||||
}
|
}
|
||||||
|
@ -47,9 +47,11 @@ func (l *WxH5AuthLogic) WxH5Auth(req *types.WXH5AuthReq) (resp *types.WXH5AuthRe
|
|||||||
|
|
||||||
// Step 3: 处理用户信息
|
// Step 3: 处理用户信息
|
||||||
var userID int64
|
var userID int64
|
||||||
|
var userType int64
|
||||||
if userAuth != nil {
|
if userAuth != nil {
|
||||||
// 已存在用户,直接登录
|
// 已存在用户,直接登录
|
||||||
userID = userAuth.UserId
|
userID = userAuth.UserId
|
||||||
|
userType = model.UserTypeNormal
|
||||||
} else {
|
} else {
|
||||||
// 检查临时用户表
|
// 检查临时用户表
|
||||||
userTemp, err := l.svcCtx.UserTempModel.FindOneByAuthTypeAuthKey(l.ctx, model.UserAuthTypeWxh5OpenID, accessTokenResp.Openid)
|
userTemp, err := l.svcCtx.UserTempModel.FindOneByAuthTypeAuthKey(l.ctx, model.UserAuthTypeWxh5OpenID, accessTokenResp.Openid)
|
||||||
@ -74,10 +76,11 @@ func (l *WxH5AuthLogic) WxH5Auth(req *types.WXH5AuthReq) (resp *types.WXH5AuthRe
|
|||||||
} else {
|
} else {
|
||||||
userID = userTemp.Id
|
userID = userTemp.Id
|
||||||
}
|
}
|
||||||
|
userType = model.UserTypeTemp
|
||||||
}
|
}
|
||||||
|
|
||||||
// Step 4: 生成JWT Token
|
// Step 4: 生成JWT Token
|
||||||
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID)
|
token, err := l.svcCtx.UserService.GeneralUserToken(l.ctx, userID, userType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成JWT token失败: %v", err)
|
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成JWT token失败: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ func (s *UserService) RegisterUUIDUser(ctx context.Context) (int64, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// generalUserToken 生成用户token
|
// generalUserToken 生成用户token
|
||||||
func (s *UserService) GeneralUserToken(ctx context.Context, userID int64) (string, error) {
|
func (s *UserService) GeneralUserToken(ctx context.Context, userID int64, userType int64) (string, error) {
|
||||||
platform, err := ctxdata.GetPlatformFromCtx(ctx)
|
platform, err := ctxdata.GetPlatformFromCtx(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
@ -85,18 +85,7 @@ func (s *UserService) GeneralUserToken(ctx context.Context, userID int64) (strin
|
|||||||
|
|
||||||
var isAgent int64
|
var isAgent int64
|
||||||
var agentID int64
|
var agentID int64
|
||||||
var userType int64
|
if userType == model.UserTypeNormal {
|
||||||
var user *model.User
|
|
||||||
users, err := s.userModel.FindAll(ctx, s.userModel.SelectBuilder().Where("id = ?", userID), "")
|
|
||||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if len(users) > 0 {
|
|
||||||
user = users[0]
|
|
||||||
}
|
|
||||||
if user != nil {
|
|
||||||
userID = user.Id
|
|
||||||
userType = model.UserTypeNormal
|
|
||||||
agent, err := s.agentModel.FindOneByUserId(ctx, userID)
|
agent, err := s.agentModel.FindOneByUserId(ctx, userID)
|
||||||
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
if err != nil && !errors.Is(err, model.ErrNotFound) {
|
||||||
return "", err
|
return "", err
|
||||||
@ -112,7 +101,6 @@ func (s *UserService) GeneralUserToken(ctx context.Context, userID int64) (strin
|
|||||||
}
|
}
|
||||||
if userTemp != nil {
|
if userTemp != nil {
|
||||||
userID = userTemp.Id
|
userID = userTemp.Id
|
||||||
userType = model.UserTypeTemp
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
token, generaErr := jwtx.GenerateJwtToken(jwtx.JwtClaims{
|
token, generaErr := jwtx.GenerateJwtToken(jwtx.JwtClaims{
|
||||||
|
393
common/jwt/jwtx_test.go
Normal file
393
common/jwt/jwtx_test.go
Normal file
@ -0,0 +1,393 @@
|
|||||||
|
package jwtx
|
||||||
|
|
||||||
|
import (
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/golang-jwt/jwt/v4"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestGenerateJwtToken(t *testing.T) {
|
||||||
|
// 测试数据
|
||||||
|
testClaims := JwtClaims{
|
||||||
|
UserId: 1,
|
||||||
|
AgentId: 0,
|
||||||
|
Platform: "wxh5",
|
||||||
|
UserType: 0,
|
||||||
|
IsAgent: 0,
|
||||||
|
}
|
||||||
|
testSecret := "WUvoIwL-FK0qnlxhvxR9tV6SjfOpeJMpKmY2QvT99lA"
|
||||||
|
testExpire := int64(2592000) // 1小时
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
claims JwtClaims
|
||||||
|
secret string
|
||||||
|
expire int64
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "正常生成token",
|
||||||
|
claims: testClaims,
|
||||||
|
secret: testSecret,
|
||||||
|
expire: testExpire,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "不同用户数据",
|
||||||
|
claims: JwtClaims{
|
||||||
|
UserId: 99999,
|
||||||
|
AgentId: 11111,
|
||||||
|
Platform: "mobile",
|
||||||
|
UserType: 0,
|
||||||
|
IsAgent: 1,
|
||||||
|
},
|
||||||
|
secret: testSecret,
|
||||||
|
expire: testExpire,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "空密钥",
|
||||||
|
claims: testClaims,
|
||||||
|
secret: "",
|
||||||
|
expire: testExpire,
|
||||||
|
wantErr: false, // 空密钥不会导致生成失败,但验证时会失败
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "零过期时间",
|
||||||
|
claims: testClaims,
|
||||||
|
secret: testSecret,
|
||||||
|
expire: 0,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "负数过期时间",
|
||||||
|
claims: testClaims,
|
||||||
|
secret: testSecret,
|
||||||
|
expire: -3600,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
token, err := GenerateJwtToken(tt.claims, tt.secret, tt.expire)
|
||||||
|
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("GenerateJwtToken() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.wantErr {
|
||||||
|
// 验证token不为空
|
||||||
|
if token == "" {
|
||||||
|
t.Error("GenerateJwtToken() 返回的token为空")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证token格式(JWT token应该包含两个点分隔符)
|
||||||
|
parts := strings.Split(token, ".")
|
||||||
|
if len(parts) != 3 {
|
||||||
|
t.Errorf("GenerateJwtToken() 返回的token格式不正确,期望3部分,实际%d部分", len(parts))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证token可以被解析(不验证签名,只验证格式)
|
||||||
|
parsedToken, err := jwt.Parse(token, func(token *jwt.Token) (interface{}, error) {
|
||||||
|
return []byte(tt.secret), nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err == nil && parsedToken != nil {
|
||||||
|
// 验证claims是否正确设置
|
||||||
|
if claims, ok := parsedToken.Claims.(jwt.MapClaims); ok {
|
||||||
|
// 验证userId
|
||||||
|
if userId, exists := claims["userId"]; exists {
|
||||||
|
if int64(userId.(float64)) != tt.claims.UserId {
|
||||||
|
t.Errorf("token中的userId不匹配,期望%d,实际%v", tt.claims.UserId, userId)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Error("token中缺少userId字段")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证extra字段存在
|
||||||
|
if _, exists := claims[ExtraKey]; !exists {
|
||||||
|
t.Error("token中缺少extra字段")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证exp字段
|
||||||
|
if exp, exists := claims["exp"]; exists {
|
||||||
|
expTime := int64(exp.(float64))
|
||||||
|
now := time.Now().Unix()
|
||||||
|
expectedExp := now + tt.expire
|
||||||
|
// 允许5秒的时间差异
|
||||||
|
if expTime < expectedExp-5 || expTime > expectedExp+5 {
|
||||||
|
t.Errorf("token过期时间不正确,期望约%d,实际%d", expectedExp, expTime)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
t.Error("token中缺少exp字段")
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证iat字段
|
||||||
|
if _, exists := claims["iat"]; !exists {
|
||||||
|
t.Error("token中缺少iat字段")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("生成的token: %s", token)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestGenerateJwtTokenAndParse(t *testing.T) {
|
||||||
|
// 测试生成token后能够正确解析
|
||||||
|
testClaims := JwtClaims{
|
||||||
|
UserId: 12345,
|
||||||
|
AgentId: 67890,
|
||||||
|
Platform: "web",
|
||||||
|
UserType: 1,
|
||||||
|
IsAgent: 0,
|
||||||
|
}
|
||||||
|
testSecret := "test-secret-key"
|
||||||
|
testExpire := int64(3600)
|
||||||
|
|
||||||
|
// 生成token
|
||||||
|
token, err := GenerateJwtToken(testClaims, testSecret, testExpire)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GenerateJwtToken() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 解析token
|
||||||
|
parsedClaims, err := ParseJwtToken(token, testSecret)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("ParseJwtToken() failed: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证解析出的claims与原始claims一致
|
||||||
|
if parsedClaims.UserId != testClaims.UserId {
|
||||||
|
t.Errorf("UserId不匹配,期望%d,实际%d", testClaims.UserId, parsedClaims.UserId)
|
||||||
|
}
|
||||||
|
if parsedClaims.AgentId != testClaims.AgentId {
|
||||||
|
t.Errorf("AgentId不匹配,期望%d,实际%d", testClaims.AgentId, parsedClaims.AgentId)
|
||||||
|
}
|
||||||
|
if parsedClaims.Platform != testClaims.Platform {
|
||||||
|
t.Errorf("Platform不匹配,期望%s,实际%s", testClaims.Platform, parsedClaims.Platform)
|
||||||
|
}
|
||||||
|
if parsedClaims.UserType != testClaims.UserType {
|
||||||
|
t.Errorf("UserType不匹配,期望%d,实际%d", testClaims.UserType, parsedClaims.UserType)
|
||||||
|
}
|
||||||
|
if parsedClaims.IsAgent != testClaims.IsAgent {
|
||||||
|
t.Errorf("IsAgent不匹配,期望%d,实际%d", testClaims.IsAgent, parsedClaims.IsAgent)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("测试通过: 生成token并成功解析,claims数据一致")
|
||||||
|
}
|
||||||
|
|
||||||
|
func BenchmarkGenerateJwtToken(t *testing.B) {
|
||||||
|
// 性能测试
|
||||||
|
testClaims := JwtClaims{
|
||||||
|
UserId: 12345,
|
||||||
|
AgentId: 67890,
|
||||||
|
Platform: "web",
|
||||||
|
UserType: 1,
|
||||||
|
IsAgent: 0,
|
||||||
|
}
|
||||||
|
testSecret := "test-secret-key"
|
||||||
|
testExpire := int64(3600)
|
||||||
|
|
||||||
|
t.ResetTimer()
|
||||||
|
for i := 0; i < t.N; i++ {
|
||||||
|
_, err := GenerateJwtToken(testClaims, testSecret, testExpire)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("GenerateJwtToken() failed: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestParseJwtToken(t *testing.T) {
|
||||||
|
// 使用你修改的测试数据
|
||||||
|
testClaims := JwtClaims{
|
||||||
|
UserId: 6,
|
||||||
|
AgentId: 0,
|
||||||
|
Platform: "wxh5",
|
||||||
|
UserType: 0,
|
||||||
|
IsAgent: 0,
|
||||||
|
}
|
||||||
|
testSecret := "WUvoIwL-FK0qnlxhvxR9tV6SjfOpeJMpKmY2QvT99lA"
|
||||||
|
testExpire := int64(2592000) // 30天
|
||||||
|
|
||||||
|
// 先生成一个token用于测试
|
||||||
|
token, err := GenerateJwtToken(testClaims, testSecret, testExpire)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("生成token失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("生成的测试token: %s", token)
|
||||||
|
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
token string
|
||||||
|
secret string
|
||||||
|
wantErr bool
|
||||||
|
wantClaims *JwtClaims
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "正常解析token",
|
||||||
|
token: token,
|
||||||
|
secret: testSecret,
|
||||||
|
wantErr: false,
|
||||||
|
wantClaims: &testClaims,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "错误的密钥",
|
||||||
|
token: token,
|
||||||
|
secret: "wrong-secret",
|
||||||
|
wantErr: true,
|
||||||
|
wantClaims: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "空token",
|
||||||
|
token: "",
|
||||||
|
secret: testSecret,
|
||||||
|
wantErr: true,
|
||||||
|
wantClaims: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "无效token格式",
|
||||||
|
token: "invalid.token.format",
|
||||||
|
secret: testSecret,
|
||||||
|
wantErr: true,
|
||||||
|
wantClaims: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "缺少点分隔符的token",
|
||||||
|
token: "invalidtoken",
|
||||||
|
secret: testSecret,
|
||||||
|
wantErr: true,
|
||||||
|
wantClaims: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "自定义token",
|
||||||
|
token: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE3NTI5MDA5MTQsImV4dHJhIjp7ImFnZW50SWQiOjAsImlzQWdlbnQiOjAsInBsYXRmb3JtIjoid3hoNSIsInVzZXJJZCI6NiwidXNlclR5cGUiOjF9LCJpYXQiOjE3NTAzMDg5MTQsInVzZXJJZCI6Nn0.GPKgLOaALOIa1ft7Hipuo4YKFf5guYt0rz2MCDCSdCQ",
|
||||||
|
secret: testSecret,
|
||||||
|
wantErr: false,
|
||||||
|
wantClaims: &testClaims,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
claims, err := ParseJwtToken(tt.token, tt.secret)
|
||||||
|
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("ParseJwtToken() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !tt.wantErr && tt.wantClaims != nil {
|
||||||
|
if claims == nil {
|
||||||
|
t.Error("ParseJwtToken() 返回的claims为nil")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// 验证各个字段
|
||||||
|
if claims.UserId != tt.wantClaims.UserId {
|
||||||
|
t.Errorf("UserId不匹配,期望%d,实际%d", tt.wantClaims.UserId, claims.UserId)
|
||||||
|
}
|
||||||
|
if claims.AgentId != tt.wantClaims.AgentId {
|
||||||
|
t.Errorf("AgentId不匹配,期望%d,实际%d", tt.wantClaims.AgentId, claims.AgentId)
|
||||||
|
}
|
||||||
|
if claims.Platform != tt.wantClaims.Platform {
|
||||||
|
t.Errorf("Platform不匹配,期望%s,实际%s", tt.wantClaims.Platform, claims.Platform)
|
||||||
|
}
|
||||||
|
if claims.UserType != tt.wantClaims.UserType {
|
||||||
|
t.Errorf("UserType不匹配,期望%d,实际%d", tt.wantClaims.UserType, claims.UserType)
|
||||||
|
}
|
||||||
|
if claims.IsAgent != tt.wantClaims.IsAgent {
|
||||||
|
t.Errorf("IsAgent不匹配,期望%d,实际%d", tt.wantClaims.IsAgent, claims.IsAgent)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("解析成功的claims: UserId=%d, AgentId=%d, Platform=%s, UserType=%d, IsAgent=%d",
|
||||||
|
claims.UserId, claims.AgentId, claims.Platform, claims.UserType, claims.IsAgent)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestParseCustomJwtToken 测试解析自定义token - 你可以在这里传入你自己的token
|
||||||
|
func TestParseCustomJwtToken(t *testing.T) {
|
||||||
|
// 在这里修改你想要测试的token和secret
|
||||||
|
customToken := "" // 在这里粘贴你的token
|
||||||
|
customSecret := "WUvoIwL-FK0qnlxhvxR9tV6SjfOpeJMpKmY2QvT99lA" // 你的密钥
|
||||||
|
|
||||||
|
// 如果没有提供自定义token,跳过测试
|
||||||
|
if customToken == "" {
|
||||||
|
t.Skip("跳过自定义token测试,请在代码中设置customToken值")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("解析自定义token: %s", customToken)
|
||||||
|
|
||||||
|
claims, err := ParseJwtToken(customToken, customSecret)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("解析自定义token失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("解析结果:")
|
||||||
|
t.Logf(" UserId: %d", claims.UserId)
|
||||||
|
t.Logf(" AgentId: %d", claims.AgentId)
|
||||||
|
t.Logf(" Platform: %s", claims.Platform)
|
||||||
|
t.Logf(" UserType: %d", claims.UserType)
|
||||||
|
t.Logf(" IsAgent: %d", claims.IsAgent)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestGenerateAndParseWithRealData 生成一个真实的token并解析
|
||||||
|
func TestGenerateAndParseWithRealData(t *testing.T) {
|
||||||
|
// 使用真实数据生成token
|
||||||
|
realClaims := JwtClaims{
|
||||||
|
UserId: 1,
|
||||||
|
AgentId: 0,
|
||||||
|
Platform: "wxh5",
|
||||||
|
UserType: 0,
|
||||||
|
IsAgent: 0,
|
||||||
|
}
|
||||||
|
realSecret := "WUvoIwL-FK0qnlxhvxR9tV6SjfOpeJMpKmY2QvT99lA"
|
||||||
|
realExpire := int64(2592000) // 30天
|
||||||
|
|
||||||
|
// 生成token
|
||||||
|
token, err := GenerateJwtToken(realClaims, realSecret, realExpire)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("生成token失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("=== 生成的完整token ===")
|
||||||
|
t.Logf("Token: %s", token)
|
||||||
|
t.Logf("========================")
|
||||||
|
|
||||||
|
// 解析token
|
||||||
|
parsedClaims, err := ParseJwtToken(token, realSecret)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("解析token失败: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Logf("=== 解析结果 ===")
|
||||||
|
t.Logf("UserId: %d", parsedClaims.UserId)
|
||||||
|
t.Logf("AgentId: %d", parsedClaims.AgentId)
|
||||||
|
t.Logf("Platform: %s", parsedClaims.Platform)
|
||||||
|
t.Logf("UserType: %d", parsedClaims.UserType)
|
||||||
|
t.Logf("IsAgent: %d", parsedClaims.IsAgent)
|
||||||
|
t.Logf("================")
|
||||||
|
|
||||||
|
// 验证数据一致性
|
||||||
|
if parsedClaims.UserId != realClaims.UserId ||
|
||||||
|
parsedClaims.AgentId != realClaims.AgentId ||
|
||||||
|
parsedClaims.Platform != realClaims.Platform ||
|
||||||
|
parsedClaims.UserType != realClaims.UserType ||
|
||||||
|
parsedClaims.IsAgent != realClaims.IsAgent {
|
||||||
|
t.Error("解析出的claims与原始数据不一致")
|
||||||
|
} else {
|
||||||
|
t.Log("✅ 数据一致性验证通过")
|
||||||
|
}
|
||||||
|
}
|
4
go.mod
4
go.mod
@ -21,6 +21,7 @@ require (
|
|||||||
github.com/shopspring/decimal v1.4.0
|
github.com/shopspring/decimal v1.4.0
|
||||||
github.com/smartwalle/alipay/v3 v3.2.23
|
github.com/smartwalle/alipay/v3 v3.2.23
|
||||||
github.com/sony/sonyflake v1.2.0
|
github.com/sony/sonyflake v1.2.0
|
||||||
|
github.com/stretchr/testify v1.10.0
|
||||||
github.com/tidwall/gjson v1.18.0
|
github.com/tidwall/gjson v1.18.0
|
||||||
github.com/wechatpay-apiv3/wechatpay-go v0.2.20
|
github.com/wechatpay-apiv3/wechatpay-go v0.2.20
|
||||||
github.com/zeromicro/go-zero v1.7.3
|
github.com/zeromicro/go-zero v1.7.3
|
||||||
@ -42,6 +43,7 @@ require (
|
|||||||
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
github.com/cespare/xxhash/v2 v2.3.0 // indirect
|
||||||
github.com/clbanning/mxj/v2 v2.5.5 // indirect
|
github.com/clbanning/mxj/v2 v2.5.5 // indirect
|
||||||
github.com/cloudwego/base64x v0.1.5 // indirect
|
github.com/cloudwego/base64x v0.1.5 // indirect
|
||||||
|
github.com/davecgh/go-spew v1.1.1 // indirect
|
||||||
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
|
||||||
github.com/fatih/color v1.17.0 // indirect
|
github.com/fatih/color v1.17.0 // indirect
|
||||||
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
github.com/gabriel-vasile/mimetype v1.4.3 // indirect
|
||||||
@ -64,6 +66,7 @@ require (
|
|||||||
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
|
||||||
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
github.com/openzipkin/zipkin-go v0.4.3 // indirect
|
||||||
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
github.com/pelletier/go-toml/v2 v2.2.2 // indirect
|
||||||
|
github.com/pmezard/go-difflib v1.0.0 // indirect
|
||||||
github.com/prometheus/client_golang v1.20.5 // indirect
|
github.com/prometheus/client_golang v1.20.5 // indirect
|
||||||
github.com/prometheus/client_model v0.6.1 // indirect
|
github.com/prometheus/client_model v0.6.1 // indirect
|
||||||
github.com/prometheus/common v0.55.0 // indirect
|
github.com/prometheus/common v0.55.0 // indirect
|
||||||
@ -100,4 +103,5 @@ require (
|
|||||||
google.golang.org/protobuf v1.35.1 // indirect
|
google.golang.org/protobuf v1.35.1 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
gopkg.in/yaml.v2 v2.4.0 // indirect
|
gopkg.in/yaml.v2 v2.4.0 // indirect
|
||||||
|
gopkg.in/yaml.v3 v3.0.1 // indirect
|
||||||
)
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user