Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: token refresh && expiration time #18

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 2 additions & 4 deletions internal/middleware/jwt/jwt.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"strconv"
"time"

"github.com/TensoRaws/NuxBT-Backend/dal/model"
"github.com/TensoRaws/NuxBT-Backend/module/config"
"github.com/TensoRaws/NuxBT-Backend/module/log"
"github.com/golang-jwt/jwt/v5"
Expand All @@ -23,15 +22,14 @@ func GetJWTSigningKey() []byte {
}

// GenerateToken 生成 jwt(json web token)
func GenerateToken(u *model.User) string {
userID := strconv.FormatInt(int64(u.UserID), 10)
func GenerateToken(userID int32) string {
claims := jwt.RegisteredClaims{
ExpiresAt: jwt.NewNumericDate(time.Now().Add(GetJWTTokenExpiredDuration())),
NotBefore: jwt.NewNumericDate(time.Now()),
Issuer: "TensoRaws",
IssuedAt: jwt.NewNumericDate(time.Now()),
Subject: "token",
ID: userID, // jwt 中保存合法用户的 ID
ID: strconv.FormatInt(int64(userID), 10), // jwt 中保存合法用户的 ID
}

// 使用指定的签名算法创建用于签名的字符串对象,使用 json 序列化和 base64Url 编码生成 jwt 的 1、2 部分
Expand Down
4 changes: 4 additions & 0 deletions internal/router/api/v1/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ func NewAPI() *gin.Engine {
user.POST("register", user_service.Register)
// 用户登录
user.POST("login", user_service.Login)
// 用户刷新 token
user.POST("token/refresh",
jwt.RequireAuth(cache.Clients[cache.JWTBlacklist], true), // 把 token 拉黑
user_service.TokenRefresh)
// 用户登出
user.POST("logout",
jwt.RequireAuth(cache.Clients[cache.JWTBlacklist], true), // 把 token 拉黑
Expand Down
34 changes: 30 additions & 4 deletions internal/service/user/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ type LoginRequest struct {
}

type LoginResponse struct {
Token string `json:"token"`
Expiration int64 `json:"expiration"`
Token string `json:"token"`
}

// Login 用户登录 (POST /login)
Expand All @@ -37,13 +38,38 @@ func Login(c *gin.Context) {
err = bcrypt.CompareHashAndPassword([]byte(user.Password), []byte(req.Password))
if err == nil {
// 注册之后的下次登录成功,才会为其生成 token
token := jwt.GenerateToken(user)
// 打印相应信息和用户信息以及生成的 token 值
token := jwt.GenerateToken(user.UserID)

claims, err := jwt.ParseToken(token)
if err != nil {
resp.AbortWithMsg(c, code.UnknownError, err.Error())
return
}

resp.OKWithData(c, LoginResponse{
Token: token,
Expiration: claims.ExpiresAt.Unix(),
Token: token,
})
} else {
resp.Abort(c, code.UserErrorInvalidPassword)
return
}
}

// TokenRefresh 用户刷新 token (POST /token/refresh)
func TokenRefresh(c *gin.Context) {
userID, _ := resp.GetUserIDFromGinContext(c)

token := jwt.GenerateToken(userID)

claims, err := jwt.ParseToken(token)
if err != nil {
resp.AbortWithMsg(c, code.UnknownError, err.Error())
return
}

resp.OKWithData(c, LoginResponse{
Expiration: claims.ExpiresAt.Unix(),
Token: token,
})
}
Loading