授权中心开发

This commit is contained in:
2025-08-04 18:15:14 +08:00
parent 968ed27a1c
commit ca53d095b6
17 changed files with 577 additions and 904 deletions

View File

@@ -151,7 +151,7 @@ func FindUser(keyword *string) (*user.UserInfoReq, error) {
}
// CheckLogin 验证登录(适配 Scrypt 加密)
func CheckLogin(username, password ,ip string) (*model.User, error) {
func CheckLogin(username, password, ip string) (*model.User, error) {
var user model.User
// 1. 查询用户(支持 user_id/手机号/用户名登录)
@@ -196,7 +196,7 @@ func CheckLogin(username, password ,ip string) (*model.User, error) {
return &user, updateLastLoginInfo(user.ID, ip)
}
// 辅助函数:更新登录信息
// 更新登录信息
func updateLastLoginInfo(userID uint, loginIP string) error {
now := time.Now()
return DB.Model(&model.User{}).Where("id = ?", userID).Updates(map[string]interface{}{
@@ -204,4 +204,3 @@ func updateLastLoginInfo(userID uint, loginIP string) error {
"last_login_time": &now,
}).Error
}

View File

@@ -1,7 +1,11 @@
package dal
import "userAuthCenter/biz/dal/mysql"
import (
"userAuthCenter/biz/dal/mysql"
"userAuthCenter/biz/dal/redis"
)
func Init() {
redis.InitRedis()
mysql.Init()
}

View File

@@ -6,11 +6,12 @@ import (
"fmt"
"golang.org/x/crypto/scrypt"
"gorm.io/gorm"
"time"
"userAuthCenter/biz/model"
)
// CheckLogin 验证登录
func CheckLogin(username, password string) (*model.User, error) {
func CheckLogin(username, password, ip string) (*model.User, error) {
var user model.User
// 1. 查询用户(支持 user_id/手机号/用户名登录)
@@ -52,5 +53,14 @@ func CheckLogin(username, password string) (*model.User, error) {
}
// 5. 更新最后登录信息
return &user, nil
return &user, updateLastLoginInfo(user.ID, ip)
}
// 更新登录信息
func updateLastLoginInfo(userID uint, loginIP string) error {
now := time.Now()
return DB.Model(&model.User{}).Where("id = ?", userID).Updates(map[string]interface{}{
"last_login_ip": loginIP,
"last_login_time": &now,
}).Error
}

View File

@@ -0,0 +1,27 @@
package redis
import (
"context"
"fmt"
"github.com/cloudwego/hertz/pkg/common/hlog"
"github.com/go-redis/redis/v8"
"userAuthCenter/config"
)
var Rdb *redis.Client
var ctx = context.Background()
// 初始化Redis连接
func InitRedis() {
Rdb = redis.NewClient(&redis.Options{
Addr: fmt.Sprintf("%s:%s", config.RedisHost, config.RedisPort),
Password: "",
DB: 0,
})
if _, err := Rdb.Ping(ctx).Result(); err != nil {
hlog.Errorf("无法连接Redis: %v", err)
panic(err)
}
hlog.Info("已连接Redis")
}

View File

@@ -0,0 +1,131 @@
package redis
import (
"context"
"errors"
"fmt"
"time"
"github.com/go-redis/redis/v8"
)
// TokenStore 处理与令牌存储相关的Redis操作
type TokenStore struct {
redisClient *redis.Client
tokenTTL time.Duration // 令牌有效期
}
// NewTokenStore 创建一个新的TokenStore实例
func NewTokenStore(redisClient *redis.Client, tokenTTL time.Duration) *TokenStore {
return &TokenStore{
redisClient: redisClient,
tokenTTL: tokenTTL,
}
}
// getUserTokensKey 生成存储用户令牌的Redis键名
func (ts *TokenStore) getUserTokensKey(username string) string {
return fmt.Sprintf("user:tokens:%s", username)
}
// getTokenBlacklistKey 生成令牌黑名单的Redis键名
func (ts *TokenStore) getTokenBlacklistKey(token string) string {
return fmt.Sprintf("blacklist:%s", token)
}
// InvalidateOldTokens 使指定用户的所有旧令牌失效
func (ts *TokenStore) InvalidateOldTokens(ctx context.Context, username string) error {
// 获取用户的所有旧令牌
oldTokens, err := ts.redisClient.SMembers(ctx, ts.getUserTokensKey(username)).Result()
if err != nil && !errors.Is(err, redis.Nil) {
return fmt.Errorf("获取旧令牌失败: %w", err)
}
// 将旧令牌加入黑名单
for _, oldToken := range oldTokens {
err := ts.redisClient.Set(ctx, ts.getTokenBlacklistKey(oldToken), "1", ts.tokenTTL).Err()
if err != nil {
// 这里可以选择记录日志但不返回错误,避免单个令牌处理失败影响整体流程
continue
}
}
// 清除用户的旧令牌列表
if len(oldTokens) > 0 {
if err := ts.redisClient.Del(ctx, ts.getUserTokensKey(username)).Err(); err != nil {
return fmt.Errorf("清除旧令牌列表失败: %w", err)
}
}
return nil
}
// StoreNewToken 存储新令牌
func (ts *TokenStore) StoreNewToken(ctx context.Context, username, token string) error {
// 将新令牌添加到用户的令牌列表
if err := ts.redisClient.SAdd(ctx, ts.getUserTokensKey(username), token).Err(); err != nil {
return fmt.Errorf("存储新令牌失败: %w", err)
}
// 设置令牌列表的过期时间
if err := ts.redisClient.Expire(ctx, ts.getUserTokensKey(username), ts.tokenTTL).Err(); err != nil {
return fmt.Errorf("设置令牌过期时间失败: %w", err)
}
return nil
}
// IsTokenValid 检查令牌是否有效
func (ts *TokenStore) IsTokenValid(ctx context.Context, username, token string) (bool, error) {
// 检查令牌是否在黑名单中
isBlacklisted, err := ts.redisClient.Exists(ctx, ts.getTokenBlacklistKey(token)).Result()
if err != nil {
return false, fmt.Errorf("检查令牌黑名单失败: %w", err)
}
if isBlacklisted > 0 {
return false, nil
}
// 检查令牌是否在用户的有效令牌列表中
exists, err := ts.redisClient.SIsMember(ctx, ts.getUserTokensKey(username), token).Result()
if err != nil {
return false, fmt.Errorf("检查令牌有效性失败: %w", err)
}
return exists, nil
}
// InvalidateToken 使指定令牌失效
func (ts *TokenStore) InvalidateToken(ctx context.Context, username, token string) error {
// 将令牌加入黑名单
if err := ts.redisClient.Set(ctx, ts.getTokenBlacklistKey(token), "1", ts.tokenTTL).Err(); err != nil {
return fmt.Errorf("将令牌加入黑名单失败: %w", err)
}
// 从用户的有效令牌列表中移除
if err := ts.redisClient.SRem(ctx, ts.getUserTokensKey(username), token).Err(); err != nil {
return fmt.Errorf("从有效令牌列表移除令牌失败: %w", err)
}
return nil
}
// ReplaceToken 替换令牌(旧令牌失效,新令牌生效)
func (ts *TokenStore) ReplaceToken(ctx context.Context, username, oldToken, newToken string) error {
userTokensKey := ts.getUserTokensKey(username)
pipe := ts.redisClient.Pipeline()
// 1. 旧令牌加入黑名单
pipe.Set(ctx, ts.getTokenBlacklistKey(oldToken), "1", ts.tokenTTL)
// 2. 移除旧令牌
pipe.SRem(ctx, userTokensKey, oldToken)
// 3. 添加新令牌
pipe.SAdd(ctx, userTokensKey, newToken)
// 4. 刷新过期时间
pipe.Expire(ctx, userTokensKey, ts.tokenTTL)
_, err := pipe.Exec(ctx)
if err != nil {
return fmt.Errorf("替换令牌失败: %w", err)
}
return nil
}

View File

@@ -4,9 +4,11 @@ package auth
import (
"context"
"github.com/hertz-contrib/sessions"
"github.com/cloudwego/hertz/pkg/common/hlog"
"net/http"
"time"
"userAuthCenter/biz/dal/mysql"
"userAuthCenter/biz/dal/redis"
"userAuthCenter/biz/model"
"userAuthCenter/biz/utils"
@@ -15,28 +17,59 @@ import (
auth "userAuthCenter/biz/model/auth"
)
// Login .
// Login 处理用户登录请求
// @router /login [POST]
func Login(ctx context.Context, c *app.RequestContext) {
var err error
var req auth.LoginReq
// 绑定并验证请求参数
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
user, err := mysql.CheckLogin(req.UserName, req.Password)
// 验证用户名和密码
user, err := mysql.CheckLogin(req.UserName, req.Password, c.ClientIP())
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
session := sessions.Default(c)
session.Set("user", req.UserName)
err = session.Save()
// 生成新的访问令牌
token, err := utils.GenerateToken(user.UserID, user.UserName)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
// 生成新的刷新令牌
refreshToken, err := utils.GenerateRefreshToken(user.UserID)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
// 初始化令牌存储
// 设置令牌有效期为24小时
tokenStore := redis.NewTokenStore(redis.Rdb, 24*time.Hour)
// 使旧令牌失效
err = tokenStore.InvalidateOldTokens(ctx, req.UserName)
if err != nil {
c.String(consts.StatusInternalServerError, "处理旧令牌失败: "+err.Error())
return
}
// 存储新令牌
err = tokenStore.StoreNewToken(ctx, req.UserName, token)
if err != nil {
c.String(consts.StatusInternalServerError, "存储新令牌失败: "+err.Error())
return
}
// 构建并返回用户信息
userInfo := model.UserInfo{
UserID: user.UserID,
UserName: user.UserName,
@@ -44,103 +77,133 @@ func Login(ctx context.Context, c *app.RequestContext) {
Age: user.Age,
Introduce: user.Introduce,
AvatarImageURL: user.AvatarImageURL,
Birthday: user.Birthday.Format("2006-01-02 15:04:05"),
Birthday: utils.GetFormattedTime(user.Birthday),
Area: user.Area,
Mobile: user.Mobile,
UserEmail: user.UserEmail,
Alias: user.Alias,
Address: user.Address,
LastLoginIP: user.LastLoginIP,
LastLoginTime: user.LastLoginTime.Format("2006-01-02 15:04:05"),
LastLoginTime: utils.GetFormattedTime(user.LastLoginTime),
Token: token,
RefreshToken: refreshToken,
}
c.JSON(consts.StatusOK, userInfo)
}
// Auth .
// @router /auth [POST]
func Auth(ctx context.Context, c *app.RequestContext) {
var err error
var req auth.AuthReq
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
session := sessions.Default(c)
username := session.Get("user")
if username == nil {
c.String(consts.StatusBadRequest, "用户未登录!")
return
}
// 生成JWT令牌
usernameStr := username.(string)
token, err := utils.GenerateToken(usernameStr, usernameStr)
if err != nil {
c.String(http.StatusInternalServerError, "生成令牌失败: %v", err)
return
}
// 生成刷新令牌
refreshToken, err := utils.GenerateRefreshToken(usernameStr)
if err != nil {
c.String(http.StatusInternalServerError, "生成刷新令牌失败: %v", err)
return
}
resp := new(auth.AuthResp)
resp.Token = token
resp.RefreshToken = refreshToken
c.JSON(consts.StatusOK, resp)
}
// Logout .
// Logout 处理用户登出请求
// @router /logout [POST]
func Logout(ctx context.Context, c *app.RequestContext) {
var err error
var req auth.LogoutReq
// 绑定并验证请求参数
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
// 清除会话
session := sessions.Default(c)
session.Clear()
session.Save()
resp := new(auth.LogoutResp)
resp.Msg = "已注销"
// 如果请求中没有提供token尝试从请求头获取
token := req.Token
if token == "" {
token = string(c.GetHeader("Authorization"))
}
if token == "" {
c.String(consts.StatusBadRequest, "请提供令牌")
return
}
hlog.Infof("req: %+v\n", req)
// 解析令牌获取用户名
username, err := utils.ParseTokenUsername(token)
if err != nil {
hlog.Errorf("token parse err: %+v\n", err)
c.String(consts.StatusBadRequest, "无效的令牌")
return
}
if username != req.UserName {
hlog.Errorf("token username not match: %+v\n", username)
c.String(consts.StatusBadRequest, "无效的令牌")
return
}
// 初始化令牌存储
tokenStore := redis.NewTokenStore(redis.Rdb, 24*time.Hour)
// 使当前令牌失效
err = tokenStore.InvalidateToken(ctx, username, token)
if err != nil {
hlog.Errorf("token invalidate error: %+v\n", err)
c.String(consts.StatusInternalServerError, "注销失败: "+err.Error())
return
}
// 返回成功响应
resp := &auth.LogoutResp{
Msg: "已成功注销",
}
c.JSON(consts.StatusOK, resp)
}
// Refresh .
// Refresh 处理令牌刷新请求
// @router /refresh [POST]
func Refresh(ctx context.Context, c *app.RequestContext) {
var err error
var req auth.RefreshReq
// 绑定并验证请求参数
err = c.BindAndValidate(&req)
if err != nil {
c.String(consts.StatusBadRequest, err.Error())
return
}
// 验证刷新令牌
tokenStore := redis.NewTokenStore(redis.Rdb, 24*time.Hour)
// 1. 验证刷新令牌
userID, err := utils.ValidateRefreshToken(req.RefreshToken)
if err != nil {
c.String(http.StatusUnauthorized, "无效的刷新令牌")
return
}
// 生成新的访问令牌
newToken, err := utils.GenerateToken(userID, userID)
if err != nil {
c.JSON(http.StatusInternalServerError, "生成新令牌失败")
c.String(http.StatusUnauthorized, "无效的刷新令牌: %v", err)
return
}
resp := new(auth.RefreshResp)
resp.NewToken = newToken
// 2. 验证旧的访问令牌(确保是有效的令牌)
oldTokenClaims, err := utils.ValidateToken(req.Token)
if err != nil {
c.String(http.StatusUnauthorized, "无效的访问令牌: %v", err)
return
}
// 3. 确保刷新令牌和访问令牌属于同一用户
if oldTokenClaims.UserID != userID {
c.String(http.StatusUnauthorized, "令牌所属用户不匹配")
return
}
// 4. 检查访问令牌是否在有效列表中
isValid, err := tokenStore.IsTokenValid(ctx, oldTokenClaims.Username, req.Token)
if err != nil {
c.String(http.StatusInternalServerError, "验证令牌状态失败: %v", err)
return
}
if !isValid {
c.String(http.StatusUnauthorized, "访问令牌已失效")
return
}
// 5. 生成新的访问令牌
newAccessToken, err := utils.GenerateToken(oldTokenClaims.UserID, oldTokenClaims.Username)
if err != nil {
c.String(http.StatusInternalServerError, "生成新访问令牌失败: %v", err)
return
}
// 6. 构建并返回响应
resp := &auth.RefreshResp{
NewToken: newAccessToken,
}
c.JSON(consts.StatusOK, resp)
}

View File

@@ -430,421 +430,9 @@ func (p *LoginResp) String() string {
}
type AuthReq struct {
UserName string `thrift:"UserName,1" form:"user_name" json:"user_name"`
}
func NewAuthReq() *AuthReq {
return &AuthReq{}
}
func (p *AuthReq) InitDefault() {
}
func (p *AuthReq) GetUserName() (v string) {
return p.UserName
}
var fieldIDToName_AuthReq = map[int16]string{
1: "UserName",
}
func (p *AuthReq) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.STRING {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_AuthReq[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *AuthReq) ReadField1(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.UserName = _field
return nil
}
func (p *AuthReq) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("AuthReq"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *AuthReq) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("UserName", thrift.STRING, 1); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.UserName); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *AuthReq) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("AuthReq(%+v)", *p)
}
type AuthResp struct {
Code Code `thrift:"code,1" form:"code" json:"code" query:"code"`
Msg string `thrift:"msg,2" form:"msg" json:"msg" query:"msg"`
Token string `thrift:"token,3" form:"token" json:"token" query:"token"`
RefreshToken string `thrift:"refresh_token,4" form:"refresh_token" json:"refresh_token" query:"refresh_token"`
}
func NewAuthResp() *AuthResp {
return &AuthResp{}
}
func (p *AuthResp) InitDefault() {
}
func (p *AuthResp) GetCode() (v Code) {
return p.Code
}
func (p *AuthResp) GetMsg() (v string) {
return p.Msg
}
func (p *AuthResp) GetToken() (v string) {
return p.Token
}
func (p *AuthResp) GetRefreshToken() (v string) {
return p.RefreshToken
}
var fieldIDToName_AuthResp = map[int16]string{
1: "code",
2: "msg",
3: "token",
4: "refresh_token",
}
func (p *AuthResp) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.I32 {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 2:
if fieldTypeId == thrift.STRING {
if err = p.ReadField2(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 3:
if fieldTypeId == thrift.STRING {
if err = p.ReadField3(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 4:
if fieldTypeId == thrift.STRING {
if err = p.ReadField4(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_AuthResp[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *AuthResp) ReadField1(iprot thrift.TProtocol) error {
var _field Code
if v, err := iprot.ReadI32(); err != nil {
return err
} else {
_field = Code(v)
}
p.Code = _field
return nil
}
func (p *AuthResp) ReadField2(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.Msg = _field
return nil
}
func (p *AuthResp) ReadField3(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.Token = _field
return nil
}
func (p *AuthResp) ReadField4(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.RefreshToken = _field
return nil
}
func (p *AuthResp) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("AuthResp"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
if err = p.writeField2(oprot); err != nil {
fieldId = 2
goto WriteFieldError
}
if err = p.writeField3(oprot); err != nil {
fieldId = 3
goto WriteFieldError
}
if err = p.writeField4(oprot); err != nil {
fieldId = 4
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *AuthResp) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("code", thrift.I32, 1); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteI32(int32(p.Code)); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *AuthResp) writeField2(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("msg", thrift.STRING, 2); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.Msg); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err)
}
func (p *AuthResp) writeField3(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("token", thrift.STRING, 3); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.Token); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 3 end error: ", p), err)
}
func (p *AuthResp) writeField4(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("refresh_token", thrift.STRING, 4); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.RefreshToken); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 4 end error: ", p), err)
}
func (p *AuthResp) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("AuthResp(%+v)", *p)
}
type LogoutReq struct {
UserName string `thrift:"UserName,1" form:"user_name" json:"user_name"`
Token string `thrift:"Token,2" form:"toekn" json:"toekn"`
}
func NewLogoutReq() *LogoutReq {
@@ -858,8 +446,13 @@ func (p *LogoutReq) GetUserName() (v string) {
return p.UserName
}
func (p *LogoutReq) GetToken() (v string) {
return p.Token
}
var fieldIDToName_LogoutReq = map[int16]string{
1: "UserName",
2: "Token",
}
func (p *LogoutReq) Read(iprot thrift.TProtocol) (err error) {
@@ -888,6 +481,14 @@ func (p *LogoutReq) Read(iprot thrift.TProtocol) (err error) {
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 2:
if fieldTypeId == thrift.STRING {
if err = p.ReadField2(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
@@ -928,6 +529,17 @@ func (p *LogoutReq) ReadField1(iprot thrift.TProtocol) error {
p.UserName = _field
return nil
}
func (p *LogoutReq) ReadField2(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.Token = _field
return nil
}
func (p *LogoutReq) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
@@ -939,6 +551,10 @@ func (p *LogoutReq) Write(oprot thrift.TProtocol) (err error) {
fieldId = 1
goto WriteFieldError
}
if err = p.writeField2(oprot); err != nil {
fieldId = 2
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
@@ -973,6 +589,22 @@ WriteFieldBeginError:
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *LogoutReq) writeField2(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("Token", thrift.STRING, 2); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.Token); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err)
}
func (p *LogoutReq) String() string {
if p == nil {
@@ -1167,7 +799,8 @@ func (p *LogoutResp) String() string {
}
type RefreshReq struct {
RefreshToken string `thrift:"refresh_token,1" form:"refresh_token" json:"refresh_token"`
Token string `thrift:"Token,1" form:"token" json:"token"`
RefreshToken string `thrift:"RefreshToken,2" form:"refresh_token" json:"refresh_token"`
}
func NewRefreshReq() *RefreshReq {
@@ -1177,12 +810,17 @@ func NewRefreshReq() *RefreshReq {
func (p *RefreshReq) InitDefault() {
}
func (p *RefreshReq) GetToken() (v string) {
return p.Token
}
func (p *RefreshReq) GetRefreshToken() (v string) {
return p.RefreshToken
}
var fieldIDToName_RefreshReq = map[int16]string{
1: "refresh_token",
1: "Token",
2: "RefreshToken",
}
func (p *RefreshReq) Read(iprot thrift.TProtocol) (err error) {
@@ -1211,6 +849,14 @@ func (p *RefreshReq) Read(iprot thrift.TProtocol) (err error) {
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
case 2:
if fieldTypeId == thrift.STRING {
if err = p.ReadField2(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
@@ -1242,6 +888,17 @@ ReadStructEndError:
func (p *RefreshReq) ReadField1(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
} else {
_field = v
}
p.Token = _field
return nil
}
func (p *RefreshReq) ReadField2(iprot thrift.TProtocol) error {
var _field string
if v, err := iprot.ReadString(); err != nil {
return err
@@ -1262,6 +919,10 @@ func (p *RefreshReq) Write(oprot thrift.TProtocol) (err error) {
fieldId = 1
goto WriteFieldError
}
if err = p.writeField2(oprot); err != nil {
fieldId = 2
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
@@ -1281,10 +942,10 @@ WriteStructEndError:
}
func (p *RefreshReq) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("refresh_token", thrift.STRING, 1); err != nil {
if err = oprot.WriteFieldBegin("Token", thrift.STRING, 1); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.RefreshToken); err != nil {
if err := oprot.WriteString(p.Token); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
@@ -1296,6 +957,22 @@ WriteFieldBeginError:
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *RefreshReq) writeField2(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("RefreshToken", thrift.STRING, 2); err != nil {
goto WriteFieldBeginError
}
if err := oprot.WriteString(p.RefreshToken); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 2 end error: ", p), err)
}
func (p *RefreshReq) String() string {
if p == nil {
@@ -1537,8 +1214,6 @@ func (p *RefreshResp) String() string {
type AuthService interface {
Login(ctx context.Context, request *LoginReq) (r *LoginResp, err error)
Auth(ctx context.Context, request *AuthReq) (r *AuthResp, err error)
Logout(ctx context.Context, request *LogoutReq) (r *LogoutResp, err error)
Refresh(ctx context.Context, request *RefreshReq) (r *RefreshResp, err error)
@@ -1579,15 +1254,6 @@ func (p *AuthServiceClient) Login(ctx context.Context, request *LoginReq) (r *Lo
}
return _result.GetSuccess(), nil
}
func (p *AuthServiceClient) Auth(ctx context.Context, request *AuthReq) (r *AuthResp, err error) {
var _args AuthServiceAuthArgs
_args.Request = request
var _result AuthServiceAuthResult
if err = p.Client_().Call(ctx, "Auth", &_args, &_result); err != nil {
return
}
return _result.GetSuccess(), nil
}
func (p *AuthServiceClient) Logout(ctx context.Context, request *LogoutReq) (r *LogoutResp, err error) {
var _args AuthServiceLogoutArgs
_args.Request = request
@@ -1628,7 +1294,6 @@ func (p *AuthServiceProcessor) ProcessorMap() map[string]thrift.TProcessorFuncti
func NewAuthServiceProcessor(handler AuthService) *AuthServiceProcessor {
self := &AuthServiceProcessor{handler: handler, processorMap: make(map[string]thrift.TProcessorFunction)}
self.AddToProcessorMap("Login", &authServiceProcessorLogin{handler: handler})
self.AddToProcessorMap("Auth", &authServiceProcessorAuth{handler: handler})
self.AddToProcessorMap("Logout", &authServiceProcessorLogout{handler: handler})
self.AddToProcessorMap("Refresh", &authServiceProcessorRefresh{handler: handler})
return self
@@ -1699,54 +1364,6 @@ func (p *authServiceProcessorLogin) Process(ctx context.Context, seqId int32, ip
return true, err
}
type authServiceProcessorAuth struct {
handler AuthService
}
func (p *authServiceProcessorAuth) Process(ctx context.Context, seqId int32, iprot, oprot thrift.TProtocol) (success bool, err thrift.TException) {
args := AuthServiceAuthArgs{}
if err = args.Read(iprot); err != nil {
iprot.ReadMessageEnd()
x := thrift.NewTApplicationException(thrift.PROTOCOL_ERROR, err.Error())
oprot.WriteMessageBegin("Auth", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return false, err
}
iprot.ReadMessageEnd()
var err2 error
result := AuthServiceAuthResult{}
var retval *AuthResp
if retval, err2 = p.handler.Auth(ctx, args.Request); err2 != nil {
x := thrift.NewTApplicationException(thrift.INTERNAL_ERROR, "Internal error processing Auth: "+err2.Error())
oprot.WriteMessageBegin("Auth", thrift.EXCEPTION, seqId)
x.Write(oprot)
oprot.WriteMessageEnd()
oprot.Flush(ctx)
return true, err2
} else {
result.Success = retval
}
if err2 = oprot.WriteMessageBegin("Auth", thrift.REPLY, seqId); err2 != nil {
err = err2
}
if err2 = result.Write(oprot); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.WriteMessageEnd(); err == nil && err2 != nil {
err = err2
}
if err2 = oprot.Flush(ctx); err == nil && err2 != nil {
err = err2
}
if err != nil {
return
}
return true, err
}
type authServiceProcessorLogout struct {
handler AuthService
}
@@ -2135,298 +1752,6 @@ func (p *AuthServiceLoginResult) String() string {
}
type AuthServiceAuthArgs struct {
Request *AuthReq `thrift:"request,1"`
}
func NewAuthServiceAuthArgs() *AuthServiceAuthArgs {
return &AuthServiceAuthArgs{}
}
func (p *AuthServiceAuthArgs) InitDefault() {
}
var AuthServiceAuthArgs_Request_DEFAULT *AuthReq
func (p *AuthServiceAuthArgs) GetRequest() (v *AuthReq) {
if !p.IsSetRequest() {
return AuthServiceAuthArgs_Request_DEFAULT
}
return p.Request
}
var fieldIDToName_AuthServiceAuthArgs = map[int16]string{
1: "request",
}
func (p *AuthServiceAuthArgs) IsSetRequest() bool {
return p.Request != nil
}
func (p *AuthServiceAuthArgs) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 1:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField1(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_AuthServiceAuthArgs[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *AuthServiceAuthArgs) ReadField1(iprot thrift.TProtocol) error {
_field := NewAuthReq()
if err := _field.Read(iprot); err != nil {
return err
}
p.Request = _field
return nil
}
func (p *AuthServiceAuthArgs) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("Auth_args"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField1(oprot); err != nil {
fieldId = 1
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *AuthServiceAuthArgs) writeField1(oprot thrift.TProtocol) (err error) {
if err = oprot.WriteFieldBegin("request", thrift.STRUCT, 1); err != nil {
goto WriteFieldBeginError
}
if err := p.Request.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 1 end error: ", p), err)
}
func (p *AuthServiceAuthArgs) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("AuthServiceAuthArgs(%+v)", *p)
}
type AuthServiceAuthResult struct {
Success *AuthResp `thrift:"success,0,optional"`
}
func NewAuthServiceAuthResult() *AuthServiceAuthResult {
return &AuthServiceAuthResult{}
}
func (p *AuthServiceAuthResult) InitDefault() {
}
var AuthServiceAuthResult_Success_DEFAULT *AuthResp
func (p *AuthServiceAuthResult) GetSuccess() (v *AuthResp) {
if !p.IsSetSuccess() {
return AuthServiceAuthResult_Success_DEFAULT
}
return p.Success
}
var fieldIDToName_AuthServiceAuthResult = map[int16]string{
0: "success",
}
func (p *AuthServiceAuthResult) IsSetSuccess() bool {
return p.Success != nil
}
func (p *AuthServiceAuthResult) Read(iprot thrift.TProtocol) (err error) {
var fieldTypeId thrift.TType
var fieldId int16
if _, err = iprot.ReadStructBegin(); err != nil {
goto ReadStructBeginError
}
for {
_, fieldTypeId, fieldId, err = iprot.ReadFieldBegin()
if err != nil {
goto ReadFieldBeginError
}
if fieldTypeId == thrift.STOP {
break
}
switch fieldId {
case 0:
if fieldTypeId == thrift.STRUCT {
if err = p.ReadField0(iprot); err != nil {
goto ReadFieldError
}
} else if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
default:
if err = iprot.Skip(fieldTypeId); err != nil {
goto SkipFieldError
}
}
if err = iprot.ReadFieldEnd(); err != nil {
goto ReadFieldEndError
}
}
if err = iprot.ReadStructEnd(); err != nil {
goto ReadStructEndError
}
return nil
ReadStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T read struct begin error: ", p), err)
ReadFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T read field %d begin error: ", p, fieldId), err)
ReadFieldError:
return thrift.PrependError(fmt.Sprintf("%T read field %d '%s' error: ", p, fieldId, fieldIDToName_AuthServiceAuthResult[fieldId]), err)
SkipFieldError:
return thrift.PrependError(fmt.Sprintf("%T field %d skip type %d error: ", p, fieldId, fieldTypeId), err)
ReadFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T read field end error", p), err)
ReadStructEndError:
return thrift.PrependError(fmt.Sprintf("%T read struct end error: ", p), err)
}
func (p *AuthServiceAuthResult) ReadField0(iprot thrift.TProtocol) error {
_field := NewAuthResp()
if err := _field.Read(iprot); err != nil {
return err
}
p.Success = _field
return nil
}
func (p *AuthServiceAuthResult) Write(oprot thrift.TProtocol) (err error) {
var fieldId int16
if err = oprot.WriteStructBegin("Auth_result"); err != nil {
goto WriteStructBeginError
}
if p != nil {
if err = p.writeField0(oprot); err != nil {
fieldId = 0
goto WriteFieldError
}
}
if err = oprot.WriteFieldStop(); err != nil {
goto WriteFieldStopError
}
if err = oprot.WriteStructEnd(); err != nil {
goto WriteStructEndError
}
return nil
WriteStructBeginError:
return thrift.PrependError(fmt.Sprintf("%T write struct begin error: ", p), err)
WriteFieldError:
return thrift.PrependError(fmt.Sprintf("%T write field %d error: ", p, fieldId), err)
WriteFieldStopError:
return thrift.PrependError(fmt.Sprintf("%T write field stop error: ", p), err)
WriteStructEndError:
return thrift.PrependError(fmt.Sprintf("%T write struct end error: ", p), err)
}
func (p *AuthServiceAuthResult) writeField0(oprot thrift.TProtocol) (err error) {
if p.IsSetSuccess() {
if err = oprot.WriteFieldBegin("success", thrift.STRUCT, 0); err != nil {
goto WriteFieldBeginError
}
if err := p.Success.Write(oprot); err != nil {
return err
}
if err = oprot.WriteFieldEnd(); err != nil {
goto WriteFieldEndError
}
}
return nil
WriteFieldBeginError:
return thrift.PrependError(fmt.Sprintf("%T write field 0 begin error: ", p), err)
WriteFieldEndError:
return thrift.PrependError(fmt.Sprintf("%T write field 0 end error: ", p), err)
}
func (p *AuthServiceAuthResult) String() string {
if p == nil {
return "<nil>"
}
return fmt.Sprintf("AuthServiceAuthResult(%+v)", *p)
}
type AuthServiceLogoutArgs struct {
Request *LogoutReq `thrift:"request,1"`
}

View File

@@ -29,19 +29,25 @@ type User struct {
ExtraInfo json.RawMessage `gorm:"column:extra_info;type:json;comment:'预留'"`
}
type UserInfo struct {
UserID string
UserName string
Gender int
Age uint8
Introduce string
AvatarImageURL string
Birthday string
Area uint8
Mobile string
UserEmail string
Alias string
Address string
LastLoginIP string
LastLoginTime string
func (u *User) TableName() string {
return "user"
}
type UserInfo struct {
UserID string `json:"user_id"`
UserName string `json:"user_name"`
Gender int `json:"gender"`
Age uint8 `json:"age"`
Introduce string `json:"introduce"`
AvatarImageURL string `json:"avatar_image_url"`
Birthday string `json:"birthday"`
Area uint8 `json:"area"`
Mobile string `json:"mobile"`
UserEmail string `json:"user_email"`
Alias string `json:"alias"`
Address string `json:"address"`
LastLoginIP string `json:"last_login_ip"`
LastLoginTime string `json:"last_login_time"`
Token string `json:"token"`
RefreshToken string `json:"refresh_token"`
}

View File

@@ -17,7 +17,6 @@ import (
func Register(r *server.Hertz) {
root := r.Group("/", rootMw()...)
root.POST("/auth", append(_authMw(), auth.Auth)...)
root.POST("/login", append(_loginMw(), auth.Login)...)
root.POST("/logout", append(_logoutMw(), auth.Logout)...)
root.POST("/refresh", append(_refreshMw(), auth.Refresh)...)

View File

@@ -3,7 +3,14 @@
package auth
import (
"context"
"errors"
"fmt"
"github.com/cloudwego/hertz/pkg/app"
"github.com/cloudwego/hertz/pkg/common/hlog"
"net/http"
"userAuthCenter/biz/dal/redis"
"userAuthCenter/biz/utils"
)
func rootMw() []app.HandlerFunc {
@@ -30,3 +37,63 @@ func _refreshMw() []app.HandlerFunc {
// your code...
return nil
}
// AuthMiddleware Hertz鉴权中间件验证请求中的令牌有效性
// 参数tokenStore - 令牌存储管理器Redis操作封装
func AuthMiddleware(tokenStore *redis.TokenStore) app.HandlerFunc {
return func(ctx context.Context, c *app.RequestContext) {
// 1. 从请求头获取令牌默认使用Authorization: Bearer {token}格式)
authHeader := c.Request.Header.Get("Authorization")
if authHeader == "" {
hlog.Warn("请求头缺少Authorization")
c.AbortWithStatusJSON(http.StatusUnauthorized, fmt.Sprintf("请登录"))
return
}
// 2. 解析Bearer令牌格式"Bearer {token}"
token, err := parseBearerToken(authHeader)
if err != nil {
hlog.Warnf("令牌格式错误: %v", err)
c.AbortWithStatusJSON(http.StatusUnauthorized, fmt.Sprintf("令牌格式错误"))
return
}
// 3. 验证JWT令牌本身的有效性签名、过期时间等
claims, err := utils.ValidateToken(token)
if err != nil {
hlog.Warnf("JWT令牌无效: %v", err)
c.AbortWithStatusJSON(http.StatusUnauthorized, fmt.Sprintf("令牌无效或已过期"))
return
}
// 4. 检查令牌在Redis中的状态是否被拉黑、是否属于当前用户
isValid, err := tokenStore.IsTokenValid(ctx, claims.Username, token)
if err != nil {
hlog.Errorf("Redis验证令牌失败: %v", err)
c.AbortWithStatusJSON(http.StatusInternalServerError, fmt.Sprintf("令牌验证失败"))
return
}
if !isValid {
hlog.Warnf("令牌已失效: username=%s, token=%s", claims.Username, token)
c.AbortWithStatusJSON(http.StatusUnauthorized, fmt.Sprintf("令牌已失效"))
return
}
// 5. 令牌验证通过,将用户信息存入上下文供后续处理使用
c.Set("userID", claims.UserID) // 存储用户ID
c.Set("username", claims.Username) // 存储用户名
c.Set("roles", claims.Roles) // 存储用户角色(如果需要权限控制)
// 继续处理后续请求
c.Next(ctx)
}
}
// parseBearerToken 从Authorization头中解析出令牌处理"Bearer {token}"格式)
func parseBearerToken(authHeader string) (string, error) {
const bearerPrefix = "Bearer "
if len(authHeader) < len(bearerPrefix) || authHeader[:len(bearerPrefix)] != bearerPrefix {
return "", errors.New("令牌格式错误")
}
return authHeader[len(bearerPrefix):], nil
}

View File

@@ -6,7 +6,6 @@ import (
"github.com/cloudwego/hertz/pkg/app/server"
auth "userAuthCenter/biz/router/auth"
hello_example "userAuthCenter/biz/router/hello/example"
login_example "userAuthCenter/biz/router/login/example"
)
// GeneratedRegister registers routers generated by IDL.
@@ -15,6 +14,4 @@ func GeneratedRegister(r *server.Hertz) {
auth.Register(r)
hello_example.Register(r)
login_example.Register(r)
}

View File

@@ -95,14 +95,16 @@ func ValidateToken(tokenString string) (*CustomClaims, error) {
)
if err != nil {
hlog.Errorf("token parse err: %+v\n", err)
return nil, err
}
// 验证令牌并提取声明
if claims, ok := token.Claims.(*CustomClaims); ok && token.Valid {
hlog.Infof("token validated: %+v\n", claims)
return claims, nil
}
hlog.Errorf("token validate err: %+v\n", err)
return nil, errors.New("无效的令牌")
}
@@ -129,6 +131,40 @@ func ValidateRefreshToken(tokenString string) (string, error) {
return "", errors.New("无效的刷新令牌")
}
// ParseTokenUsername 从JWT令牌中解析出用户名
// 该函数会先验证令牌的有效性,然后返回用户名
func ParseTokenUsername(tokenString string) (string, error) {
// 先使用已有的ValidateToken函数验证令牌并获取声明
claims, err := ValidateToken(tokenString)
if err != nil {
hlog.Errorf("解析令牌失败: %v", err)
return "", err
}
// 检查用户名是否存在
if claims.Username == "" {
hlog.Errorf("username is empty")
return "", errors.New("令牌中不包含用户名信息")
}
return claims.Username, nil
}
// ParseTokenUserID 从JWT令牌中解析出用户ID补充函数方便获取用户ID
func ParseTokenUserID(tokenString string) (string, error) {
claims, err := ValidateToken(tokenString)
if err != nil {
hlog.Errorf("解析令牌失败: %v", err)
return "", err
}
if claims.UserID == "" {
return "", errors.New("令牌中不包含用户ID信息")
}
return claims.UserID, nil
}
// ScryptPw 密码加密
func ScryptPw(password string) (string, string) {
const KEyLen = 10
@@ -148,3 +184,11 @@ func ScryptPw(password string) (string, string) {
fpw := base64.StdEncoding.EncodeToString(HashPw)
return fpw, base64.URLEncoding.EncodeToString(salt)
}
// GetFormattedTime 函数处理日期格式化
func GetFormattedTime(birthday *time.Time) string {
if birthday == nil {
return "" // 或返回默认值,如"未设置"
}
return birthday.Format("2006-01-02 15:04:05")
}

View File

@@ -20,4 +20,11 @@ DbName = iuqt_acquaintances
EtcdPort = 2379
EtcdHost = 127.0.0.1
EtcdUser = root
EtcdPassword = sixqin@123
EtcdPassword = sixqin@123
#redis参数
[redis]
RedisHost = 127.0.0.1
RedisPort = 6379
RedisUser = root
RedisPassWord =

View File

@@ -36,6 +36,12 @@ var (
EtcdHost string
EtcdUser string
EtcdPassword string
//redis
RedisHost string
RedisPort string
RedisUser string
RedisPassWord string
)
// 初始化函数
@@ -47,6 +53,7 @@ func init() {
LoadServer(file)
LoadDb(file)
LoadEtcd(file)
LoadRedis(file)
}
// 读取服务器配置
@@ -75,3 +82,11 @@ func LoadEtcd(file *ini.File) {
EtcdUser = file.Section("etcd").Key("EtcdUser").MustString("root")
EtcdPassword = file.Section("etcd").Key("EtcdPassWord").MustString("sixqin@123")
}
// 读取redis配置
func LoadRedis(file *ini.File) {
RedisHost = file.Section("redis").Key("RedisHost").MustString("127.0.0.1")
RedisPort = file.Section("redis").Key("RedisPort").MustString("6379")
RedisUser = file.Section("redis").Key("RedisUser").MustString("root")
RedisPassWord = file.Section("redis").Key("RedisPassWord").MustString("123456")
}

View File

@@ -6,7 +6,9 @@ require (
github.com/apache/thrift v0.13.0
github.com/cloudwego/hertz v0.10.1
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/go-redis/redis/v8 v8.11.5
github.com/hertz-contrib/registry/etcd v0.0.0-20250319055937-8a220332e808
github.com/redis/go-redis/v9 v9.3.0
golang.org/x/crypto v0.22.0
gopkg.in/ini.v1 v1.51.0
gorm.io/driver/mysql v1.6.0
@@ -18,19 +20,17 @@ require (
github.com/bytedance/gopkg v0.1.1 // indirect
github.com/bytedance/sonic v1.13.2 // indirect
github.com/bytedance/sonic/loader v0.2.4 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cloudwego/base64x v0.1.5 // indirect
github.com/cloudwego/gopkg v0.1.4 // indirect
github.com/cloudwego/netpoll v0.7.0 // indirect
github.com/coreos/go-semver v0.3.0 // indirect
github.com/coreos/go-systemd/v22 v22.3.2 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/fsnotify/fsnotify v1.5.4 // indirect
github.com/go-sql-driver/mysql v1.8.1 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/gorilla/context v1.1.2 // indirect
github.com/gorilla/securecookie v1.1.2 // indirect
github.com/gorilla/sessions v1.2.2 // indirect
github.com/hertz-contrib/sessions v1.0.3 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/klauspost/cpuid/v2 v2.0.9 // indirect

View File

@@ -33,17 +33,14 @@ github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs=
github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c=
github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA=
github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0=
github.com/bytedance/go-tagexpr/v2 v2.9.2/go.mod h1:5qsx05dYOiUXOUgnQ7w3Oz8BYs2qtM/bJokdLb79wRM=
github.com/bytedance/gopkg v0.0.0-20220413063733-65bf48ffb3a7/go.mod h1:2ZlV9BaUH4+NXIBF0aMdKKAnHTzqH+iMU4KUjAbL23Q=
github.com/bytedance/gopkg v0.1.0/go.mod h1:FtQG3YbQG9L/91pbKSw787yBQPutC+457AvDW77fgUQ=
github.com/bytedance/gopkg v0.1.1 h1:3azzgSkiaw79u24a+w9arfH8OfnQQ4MHUt9lJFREEaE=
github.com/bytedance/gopkg v0.1.1/go.mod h1:576VvJ+eJgyCzdjS+c4+77QF3p7ubbtiKARP3TxducM=
github.com/bytedance/mockey v1.2.1/go.mod h1:+Jm/fzWZAuhEDrPXVjDf/jLM2BlLXJkwk94zf2JZ3X4=
github.com/bytedance/mockey v1.2.12/go.mod h1:3ZA4MQasmqC87Tw0w7Ygdy7eHIc2xgpZ8Pona5rsYIk=
github.com/bytedance/sonic v1.5.0/go.mod h1:ED5hyg4y6t3/9Ku1R6dU/4KyJ48DZ4jPhfY1O2AihPM=
github.com/bytedance/sonic v1.8.1/go.mod h1:i736AoUSYt75HyZLoJW9ERYxcy6eaN6h4BZXU064P/U=
github.com/bytedance/sonic v1.12.7/go.mod h1:tnbal4mxOMju17EGfknm2XyYcpyCnIROYOEYuemj13I=
github.com/bytedance/sonic v1.13.2 h1:8/H1FempDZqC4VqjptGo14QQlJx8VdZJegxs6wwfqpQ=
github.com/bytedance/sonic v1.13.2/go.mod h1:o68xyaF9u2gvVBuGHPlUVCy+ZfmNNO5ETf1+KgkJhz4=
@@ -56,25 +53,20 @@ github.com/cenkalti/backoff/v4 v4.1.1/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInq
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44=
github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chenzhuoyu/base64x v0.0.0-20211019084208-fb5309c8db06/go.mod h1:DH46F32mSOjUmXrMHnKwZdA8wcEefY7UVqBKYGjpdQY=
github.com/chenzhuoyu/base64x v0.0.0-20221115062448-fe3a3abad311/go.mod h1:b583jCggY9gE99b6G5LEC39OIiVsWj+R97kbl5odCEk=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/base64x v0.1.5 h1:XPciSp1xaq2VCSt6lF0phncD4koWyULpl5bUxbfCyP4=
github.com/cloudwego/base64x v0.1.5/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w=
github.com/cloudwego/gopkg v0.1.4 h1:EoQiCG4sTonTPHxOGE0VlQs+sQR+Hsi2uN0qqwu8O50=
github.com/cloudwego/gopkg v0.1.4/go.mod h1:FQuXsRWRsSqJLsMVd5SYzp8/Z1y5gXKnVvRrWUOsCMI=
github.com/cloudwego/hertz v0.7.2/go.mod h1:WliNtVbwihWHHgAaIQEbVXl0O3aWj0ks1eoPrcEAnjs=
github.com/cloudwego/hertz v0.9.6/go.mod h1:X5Ez52XhtszU4t+CTBGIJI4PqmcI1oSf8ULBz0SWfLo=
github.com/cloudwego/hertz v0.10.1 h1:gTM2JIGO7vmRoaDz71GctyoUE19pXGuznFX55HjGs1g=
github.com/cloudwego/hertz v0.10.1/go.mod h1:0sofikwk5YcHCerClgCzcaoamY61JiRwR5G0mAUo+Y0=
github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY=
github.com/cloudwego/netpoll v0.5.0/go.mod h1:xVefXptcyheopwNDZjDPcfU6kIjZXZ4nY550k1yH9eQ=
github.com/cloudwego/netpoll v0.6.4/go.mod h1:BtM+GjKTdwKoC8IOzD08/+8eEn2gYoiNLipFca6BVXQ=
github.com/cloudwego/netpoll v0.7.0 h1:bDrxQaNfijRI1zyGgXHQoE/nYegL0nr+ijO1Norelc4=
github.com/cloudwego/netpoll v0.7.0/go.mod h1:PI+YrmyS7cIr0+SD4seJz3Eo3ckkXdu2ZVKBLhURLNU=
@@ -102,6 +94,7 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78=
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
@@ -127,6 +120,8 @@ github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vb
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC0oI=
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=
github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
@@ -160,7 +155,6 @@ github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaS
github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx4u74HPM=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/gomodule/redigo v1.8.9/go.mod h1:7ArFNvsTjH8GMMzB4uy1snslv2BwmginuMs06a1uzZE=
github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4=
@@ -175,7 +169,6 @@ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg=
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc=
@@ -185,12 +178,6 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o=
github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM=
github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA=
github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo=
github.com/gorilla/sessions v1.2.2 h1:lqzMYz6bOfvn2WriPUjNByzeXIlVzURcPmgMczkmTjY=
github.com/gorilla/sessions v1.2.2/go.mod h1:ePLdVu+jbEgHH+KWw8I1z2wqd0BAdAQh/8LRvBeoNcQ=
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
@@ -221,13 +208,8 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
github.com/hashicorp/mdns v1.0.0/go.mod h1:tL+uN++7HEJ6SQLQ2/p+z2pH24WQKWjBPkE0mNTz8vQ=
github.com/hashicorp/memberlist v0.1.3/go.mod h1:ajVTdAv/9Im8oMAAj5G31PhhMCZJV2pPBoIllUwCN7I=
github.com/hashicorp/serf v0.8.2/go.mod h1:6hOLApaqBFA1NXqRQAsxw9QxuDEvNxSQRwA/JwenrHc=
github.com/henrylee2cn/ameda v1.4.8/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4=
github.com/henrylee2cn/ameda v1.4.10/go.mod h1:liZulR8DgHxdK+MEwvZIylGnmcjzQ6N6f2PlWe7nEO4=
github.com/henrylee2cn/goutil v0.0.0-20210127050712-89660552f6f8/go.mod h1:Nhe/DM3671a5udlv2AdV2ni/MZzgfv2qrPL5nIi3EGQ=
github.com/hertz-contrib/registry/etcd v0.0.0-20250319055937-8a220332e808 h1:lxr8/UejpKb5mZ7D27fIFZNwm0qn/exw38wtDYd2F5Q=
github.com/hertz-contrib/registry/etcd v0.0.0-20250319055937-8a220332e808/go.mod h1:r1ek0FpFPqYRnsIG8vhM40NQMPpCE/RO9NaiUQv+vS4=
github.com/hertz-contrib/sessions v1.0.3 h1:lXBcmpPlMUhVSua54lxrIzJwhKXaI6zZcc+RgQx8xrE=
github.com/hertz-contrib/sessions v1.0.3/go.mod h1:46/DHSScV2EcK08er3IFvGHbh6a7VLMMiMlI+30QXoA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E=
github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc=
@@ -282,9 +264,15 @@ github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE=
github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU=
github.com/nyaruka/phonenumbers v1.0.55 h1:bj0nTO88Y68KeUQ/n3Lo2KgK7lM1hF7L9NFuwcCl3yg=
github.com/nyaruka/phonenumbers v1.0.55/go.mod h1:sDaTZ/KPX5f8qyV9qN+hIm+4ZBARJrupC6LuhshJq1U=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU=
github.com/onsi/gomega v1.18.1 h1:M1GfJqGRrBrrGGsbxzV5dqM2U2ApXefZCQpkukxYRLE=
github.com/onsi/gomega v1.18.1/go.mod h1:0q+aL8jAiMXy9hbwj2mr5GziHiwhAIQpFmmtT5hitRs=
github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic=
@@ -319,6 +307,7 @@ github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4O
github.com/prometheus/procfs v0.6.0 h1:mxy4L2jP6qMonqmq+aTtOx1ifVWUgG/TAmntgbh3xv4=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0=
github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
@@ -367,7 +356,6 @@ github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8
github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tidwall/gjson v1.9.3/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/gjson v1.14.4 h1:uo0p8EbA09J7RQaflQ1aBRffTR7xedD2bcIVSYxLnkM=
github.com/tidwall/gjson v1.14.4/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk=
github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA=
@@ -547,7 +535,6 @@ golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220110181412-a018aaa089fe/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220412211240-33da011f77ad/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -675,6 +662,8 @@ gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/natefinch/lumberjack.v2 v2.0.0 h1:1Lc07Kr7qY4U2YPouBjpCLxpiyxIVoxqXgkXLknAOE8=
gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

View File

@@ -17,19 +17,9 @@ struct LoginResp {
2: string msg
}
struct AuthReq{
1: string UserName (api.body="user_name");
}
struct AuthResp {
1: Code code
2: string msg
3: string token
4: string refresh_token
}
struct LogoutReq{
1: string UserName (api.body="user_name");
2: string Token (api.body="toekn");
}
struct LogoutResp {
@@ -38,7 +28,8 @@ struct LogoutResp {
}
struct RefreshReq{
1: string refresh_token (api.body="refresh_token");
1: string Token (api.body="token");
2: string RefreshToken (api.body="refresh_token");
}
struct RefreshResp {
@@ -50,7 +41,6 @@ struct RefreshResp {
service AuthService {
LoginResp Login(1: LoginReq request) (api.post="/login");
AuthResp Auth(1: AuthReq request) (api.post="/auth");
LogoutResp Logout(1: LogoutReq request) (api.post="/logout");
RefreshResp Refresh(1: RefreshReq request) (api.post="/refresh");
}