初始化
This commit is contained in:
48
pkg/jwtutil/jwtutil.go
Normal file
48
pkg/jwtutil/jwtutil.go
Normal file
@@ -0,0 +1,48 @@
|
||||
// Package jwtutil 封装 JWT Token 的签发与解析
|
||||
package jwtutil
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
|
||||
"nl-game-api-gin/internal/config"
|
||||
)
|
||||
|
||||
// Claims 自定义 JWT 载荷:用户ID与角色
|
||||
type Claims struct {
|
||||
UserID int `json:"user_id"` // 用户ID
|
||||
Role int `json:"role"` // 角色:1超管 2普通
|
||||
jwt.RegisteredClaims
|
||||
}
|
||||
|
||||
// Generate 为用户签发 Token
|
||||
func Generate(userID, role int) (string, error) {
|
||||
claims := Claims{
|
||||
UserID: userID,
|
||||
Role: role,
|
||||
RegisteredClaims: jwt.RegisteredClaims{
|
||||
// 过期时间从配置文件读取
|
||||
ExpiresAt: jwt.NewNumericDate(time.Now().Add(time.Duration(config.C.JWT.ExpireHours) * time.Hour)),
|
||||
IssuedAt: jwt.NewNumericDate(time.Now()),
|
||||
},
|
||||
}
|
||||
token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
|
||||
return token.SignedString([]byte(config.C.JWT.Secret))
|
||||
}
|
||||
|
||||
// Parse 解析并校验 Token,返回载荷
|
||||
func Parse(tokenStr string) (*Claims, error) {
|
||||
token, err := jwt.ParseWithClaims(tokenStr, &Claims{}, func(t *jwt.Token) (any, error) {
|
||||
return []byte(config.C.JWT.Secret), nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
claims, ok := token.Claims.(*Claims)
|
||||
if !ok || !token.Valid {
|
||||
return nil, errors.New("无效的 Token")
|
||||
}
|
||||
return claims, nil
|
||||
}
|
||||
29
pkg/resp/resp.go
Normal file
29
pkg/resp/resp.go
Normal file
@@ -0,0 +1,29 @@
|
||||
// Package resp 提供统一的 JSON 响应格式:{code, msg, data}
|
||||
// code=0 表示成功,非 0 表示业务失败
|
||||
package resp
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
// OK 成功响应,data 为业务数据
|
||||
func OK(c *gin.Context, data any) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 0, "msg": "ok", "data": data})
|
||||
}
|
||||
|
||||
// Fail 业务失败响应(HTTP 仍为 200,靠 code 区分)
|
||||
func Fail(c *gin.Context, msg string) {
|
||||
c.JSON(http.StatusOK, gin.H{"code": 1, "msg": msg, "data": nil})
|
||||
}
|
||||
|
||||
// Unauthorized 未登录/凭证失效响应(HTTP 401,前端据此跳转登录页)
|
||||
func Unauthorized(c *gin.Context, msg string) {
|
||||
c.AbortWithStatusJSON(http.StatusUnauthorized, gin.H{"code": 401, "msg": msg, "data": nil})
|
||||
}
|
||||
|
||||
// Forbidden 无权限响应(HTTP 403)
|
||||
func Forbidden(c *gin.Context, msg string) {
|
||||
c.AbortWithStatusJSON(http.StatusForbidden, gin.H{"code": 403, "msg": msg, "data": nil})
|
||||
}
|
||||
Reference in New Issue
Block a user