| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- package auth
- import (
- "errors"
- "time"
- "perms-system-server/internal/consts"
- "perms-system-server/internal/middleware"
- "github.com/golang-jwt/jwt/v4"
- )
- var ErrTokenTypeMismatch = errors.New("token type mismatch")
- type RefreshClaims struct {
- TokenType string `json:"tokenType"`
- UserId int64 `json:"userId"`
- ProductCode string `json:"productCode"`
- TokenVersion int64 `json:"tokenVersion"`
- jwt.RegisteredClaims
- }
- func GenerateAccessToken(secret string, expireSeconds int64, userId int64, username, productCode, memberType string, tokenVersion int64) (string, error) {
- now := time.Now()
- claims := middleware.Claims{
- TokenType: consts.TokenTypeAccess,
- UserId: userId,
- Username: username,
- ProductCode: productCode,
- MemberType: memberType,
- TokenVersion: tokenVersion,
- RegisteredClaims: jwt.RegisteredClaims{
- ExpiresAt: jwt.NewNumericDate(now.Add(time.Duration(expireSeconds) * time.Second)),
- IssuedAt: jwt.NewNumericDate(now),
- },
- }
- token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
- return token.SignedString([]byte(secret))
- }
- func GenerateRefreshToken(secret string, expireSeconds int64, userId int64, productCode string, tokenVersion int64) (string, error) {
- now := time.Now()
- claims := RefreshClaims{
- TokenType: consts.TokenTypeRefresh,
- UserId: userId,
- ProductCode: productCode,
- TokenVersion: tokenVersion,
- RegisteredClaims: jwt.RegisteredClaims{
- ExpiresAt: jwt.NewNumericDate(now.Add(time.Duration(expireSeconds) * time.Second)),
- IssuedAt: jwt.NewNumericDate(now),
- },
- }
- token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
- return token.SignedString([]byte(secret))
- }
- // GenerateRefreshTokenWithExpiry 签发 refreshToken,使用绝对过期时间(用于 token 轮转场景)。
- func GenerateRefreshTokenWithExpiry(secret string, expiresAt time.Time, userId int64, productCode string, tokenVersion int64) (string, error) {
- now := time.Now()
- if !expiresAt.After(now) {
- return "", errors.New("refresh token has expired")
- }
- claims := RefreshClaims{
- TokenType: consts.TokenTypeRefresh,
- UserId: userId,
- ProductCode: productCode,
- TokenVersion: tokenVersion,
- RegisteredClaims: jwt.RegisteredClaims{
- ExpiresAt: jwt.NewNumericDate(expiresAt),
- IssuedAt: jwt.NewNumericDate(now),
- },
- }
- token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
- return token.SignedString([]byte(secret))
- }
- func ParseRefreshToken(tokenStr, secret string) (*RefreshClaims, error) {
- token, err := jwt.ParseWithClaims(tokenStr, &RefreshClaims{}, func(token *jwt.Token) (interface{}, error) {
- return []byte(secret), nil
- })
- if err != nil {
- return nil, err
- }
- claims, ok := token.Claims.(*RefreshClaims)
- if !ok || !token.Valid {
- return nil, jwt.ErrSignatureInvalid
- }
- if claims.TokenType != consts.TokenTypeRefresh {
- return nil, ErrTokenTypeMismatch
- }
- return claims, nil
- }
|