guard/internal/logic/tokenservice/new_token_logic.go

139 lines
3.8 KiB
Go
Raw Normal View History

2024-08-10 01:52:23 +00:00
package tokenservicelogic
import (
2024-08-11 12:21:42 +00:00
"ark-permission/internal/config"
2024-08-06 05:59:24 +00:00
"ark-permission/internal/domain"
"ark-permission/internal/entity"
2024-08-08 03:02:13 +00:00
ers "code.30cm.net/wanderland/library-go/errors"
2024-08-06 05:59:24 +00:00
"context"
"github.com/google/uuid"
"time"
2024-08-10 01:52:23 +00:00
"ark-permission/gen_result/pb/permission"
"ark-permission/internal/svc"
"github.com/zeromicro/go-zero/core/logx"
)
type NewTokenLogic struct {
ctx context.Context
svcCtx *svc.ServiceContext
logx.Logger
}
func NewNewTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NewTokenLogic {
return &NewTokenLogic{
ctx: ctx,
svcCtx: svcCtx,
Logger: logx.WithContext(ctx),
}
}
2024-08-06 05:59:24 +00:00
// https://datatracker.ietf.org/doc/html/rfc6749#section-3.3
type authorizationReq struct {
2024-08-11 12:21:42 +00:00
GrantType domain.GrantType `json:"grant_type" validate:"required,oneof=password client_credentials refresh_token"`
DeviceID string `json:"device_id"`
Scope string `json:"scope" validate:"required"`
Data map[string]string `json:"data"`
Expires int `json:"expires"`
IsRefreshToken bool `json:"is_refresh_token"`
2024-08-06 05:59:24 +00:00
}
// NewToken 建立一個新的 Token例如AccessToken
func (l *NewTokenLogic) NewToken(in *permission.AuthorizationReq) (*permission.TokenResp, error) {
2024-08-11 12:21:42 +00:00
data := authorizationReq{
GrantType: domain.GrantType(in.GetGrantType()),
Scope: in.GetScope(),
DeviceID: in.GetDeviceId(),
Data: in.GetData(),
Expires: int(in.GetExpires()),
IsRefreshToken: in.GetIsRefreshToken(),
}
2024-08-06 05:59:24 +00:00
// 驗證所需
2024-08-11 12:21:42 +00:00
if err := l.svcCtx.Validate.ValidateAll(&data); err != nil {
2024-08-06 05:59:24 +00:00
return nil, ers.InvalidFormat(err.Error())
}
2024-08-11 12:21:42 +00:00
token, err := newToken(data, l.svcCtx.Config)
if err != nil {
return nil, err
}
err = l.svcCtx.TokenRedisRepo.Create(l.ctx, *token)
if err != nil {
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "TokenRedisRepo.Create"),
logx.Field("token", token),
).Error(err.Error())
return nil, err
}
return &permission.TokenResp{
AccessToken: token.AccessToken,
TokenType: domain.TokenTypeBearer,
ExpiresIn: int32(token.ExpiresIn),
RefreshToken: token.RefreshToken,
}, nil
}
2024-08-06 05:59:24 +00:00
2024-08-11 12:21:42 +00:00
func newToken(authReq authorizationReq, cfg config.Config) (*entity.Token, error) {
2024-08-06 05:59:24 +00:00
// 準備建立 Token 所需
now := time.Now().UTC()
2024-08-11 12:21:42 +00:00
expires := authReq.Expires
refreshExpires := authReq.Expires
2024-08-06 05:59:24 +00:00
if expires <= 0 {
2024-08-10 01:52:23 +00:00
// 將時間加上 300 秒
2024-08-11 12:21:42 +00:00
sec := time.Duration(cfg.Token.Expired.Seconds()) * time.Second
2024-08-10 01:52:23 +00:00
newTime := now.Add(sec)
// 獲取 Unix 時間戳
timestamp := newTime.Unix()
expires = int(timestamp)
2024-08-06 05:59:24 +00:00
refreshExpires = expires
}
// 如果這是一個 Refresh Token 過期時間要比普通的Token 長
2024-08-11 12:21:42 +00:00
if authReq.IsRefreshToken {
2024-08-10 01:52:23 +00:00
// 將時間加上 300 秒
2024-08-11 12:21:42 +00:00
sec := time.Duration(cfg.Token.RefreshExpires.Seconds()) * time.Second
2024-08-10 01:52:23 +00:00
newTime := now.Add(sec)
// 獲取 Unix 時間戳
timestamp := newTime.Unix()
refreshExpires = int(timestamp)
2024-08-06 05:59:24 +00:00
}
token := entity.Token{
ID: uuid.Must(uuid.NewRandom()).String(),
2024-08-11 12:21:42 +00:00
DeviceID: authReq.DeviceID,
2024-08-06 05:59:24 +00:00
ExpiresIn: expires,
RefreshExpiresIn: refreshExpires,
AccessCreateAt: now,
RefreshCreateAt: now,
}
2024-08-11 12:21:42 +00:00
claims := claims(authReq.Data)
2024-08-06 05:59:24 +00:00
claims.SetRole(domain.DefaultRole)
claims.SetID(token.ID)
2024-08-11 12:21:42 +00:00
claims.SetScope(authReq.Scope)
2024-08-06 05:59:24 +00:00
token.UID = claims.UID()
2024-08-11 12:21:42 +00:00
if authReq.DeviceID != "" {
claims.SetDeviceID(authReq.DeviceID)
2024-08-06 05:59:24 +00:00
}
var err error
2024-08-11 12:21:42 +00:00
token.AccessToken, err = generateAccessTokenFunc(token, claims, cfg.Token.Secret)
2024-08-06 05:59:24 +00:00
if err != nil {
2024-08-08 08:10:38 +00:00
logx.WithCallerSkip(1).WithFields(
logx.Field("func", "generateAccessTokenFunc"),
logx.Field("claims", claims),
).Error(err.Error())
return nil, err
2024-08-06 05:59:24 +00:00
}
2024-08-11 12:21:42 +00:00
if authReq.IsRefreshToken {
2024-08-06 07:52:42 +00:00
token.RefreshToken = generateRefreshTokenFunc(token.AccessToken)
2024-08-06 05:59:24 +00:00
}
2024-08-11 12:21:42 +00:00
return &token, nil
2024-08-06 05:59:24 +00:00
}