feat/create_new_token #2
|
@ -0,0 +1,45 @@
|
||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// Source: permission.proto
|
||||||
|
|
||||||
|
package permissionservice
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
AuthorizationReq = permission.AuthorizationReq
|
||||||
|
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
|
||||||
|
CancelTokenReq = permission.CancelTokenReq
|
||||||
|
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
|
||||||
|
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
|
||||||
|
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
|
||||||
|
DoTokenByUIDReq = permission.DoTokenByUIDReq
|
||||||
|
OKResp = permission.OKResp
|
||||||
|
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
|
||||||
|
RefreshTokenReq = permission.RefreshTokenReq
|
||||||
|
RefreshTokenResp = permission.RefreshTokenResp
|
||||||
|
Token = permission.Token
|
||||||
|
TokenResp = permission.TokenResp
|
||||||
|
Tokens = permission.Tokens
|
||||||
|
ValidationTokenReq = permission.ValidationTokenReq
|
||||||
|
ValidationTokenResp = permission.ValidationTokenResp
|
||||||
|
|
||||||
|
PermissionService interface {
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultPermissionService struct {
|
||||||
|
cli zrpc.Client
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewPermissionService(cli zrpc.Client) PermissionService {
|
||||||
|
return &defaultPermissionService{
|
||||||
|
cli: cli,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,51 @@
|
||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// Source: permission.proto
|
||||||
|
|
||||||
|
package roleservice
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
AuthorizationReq = permission.AuthorizationReq
|
||||||
|
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
|
||||||
|
CancelTokenReq = permission.CancelTokenReq
|
||||||
|
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
|
||||||
|
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
|
||||||
|
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
|
||||||
|
DoTokenByUIDReq = permission.DoTokenByUIDReq
|
||||||
|
OKResp = permission.OKResp
|
||||||
|
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
|
||||||
|
RefreshTokenReq = permission.RefreshTokenReq
|
||||||
|
RefreshTokenResp = permission.RefreshTokenResp
|
||||||
|
Token = permission.Token
|
||||||
|
TokenResp = permission.TokenResp
|
||||||
|
Tokens = permission.Tokens
|
||||||
|
ValidationTokenReq = permission.ValidationTokenReq
|
||||||
|
ValidationTokenResp = permission.ValidationTokenResp
|
||||||
|
|
||||||
|
RoleService interface {
|
||||||
|
Ping(ctx context.Context, in *OKResp, opts ...grpc.CallOption) (*OKResp, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultRoleService struct {
|
||||||
|
cli zrpc.Client
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewRoleService(cli zrpc.Client) RoleService {
|
||||||
|
return &defaultRoleService{
|
||||||
|
cli: cli,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *defaultRoleService) Ping(ctx context.Context, in *OKResp, opts ...grpc.CallOption) (*OKResp, error) {
|
||||||
|
client := permission.NewRoleServiceClient(m.cli.Conn())
|
||||||
|
return client.Ping(ctx, in, opts...)
|
||||||
|
}
|
|
@ -0,0 +1,125 @@
|
||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// Source: permission.proto
|
||||||
|
|
||||||
|
package tokenservice
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/zrpc"
|
||||||
|
"google.golang.org/grpc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type (
|
||||||
|
AuthorizationReq = permission.AuthorizationReq
|
||||||
|
CancelOneTimeTokenReq = permission.CancelOneTimeTokenReq
|
||||||
|
CancelTokenReq = permission.CancelTokenReq
|
||||||
|
CreateOneTimeTokenReq = permission.CreateOneTimeTokenReq
|
||||||
|
CreateOneTimeTokenResp = permission.CreateOneTimeTokenResp
|
||||||
|
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
|
||||||
|
DoTokenByUIDReq = permission.DoTokenByUIDReq
|
||||||
|
OKResp = permission.OKResp
|
||||||
|
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
|
||||||
|
RefreshTokenReq = permission.RefreshTokenReq
|
||||||
|
RefreshTokenResp = permission.RefreshTokenResp
|
||||||
|
Token = permission.Token
|
||||||
|
TokenResp = permission.TokenResp
|
||||||
|
Tokens = permission.Tokens
|
||||||
|
ValidationTokenReq = permission.ValidationTokenReq
|
||||||
|
ValidationTokenResp = permission.ValidationTokenResp
|
||||||
|
|
||||||
|
TokenService interface {
|
||||||
|
// NewToken 建立一個新的 Token,例如:AccessToken
|
||||||
|
NewToken(ctx context.Context, in *AuthorizationReq, opts ...grpc.CallOption) (*TokenResp, error)
|
||||||
|
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
|
||||||
|
RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error)
|
||||||
|
// CancelToken 取消 Token,也包含他裡面的 One Time Toke
|
||||||
|
CancelToken(ctx context.Context, in *CancelTokenReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||||
|
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
||||||
|
CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||||
|
// CancelTokenByDeviceId 取消 Token
|
||||||
|
CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||||
|
// ValidationToken 驗證這個 Token 有沒有效
|
||||||
|
ValidationToken(ctx context.Context, in *ValidationTokenReq, opts ...grpc.CallOption) (*ValidationTokenResp, error)
|
||||||
|
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
|
||||||
|
GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error)
|
||||||
|
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
|
||||||
|
GetUserTokensByUid(ctx context.Context, in *QueryTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error)
|
||||||
|
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
||||||
|
NewOneTimeToken(ctx context.Context, in *CreateOneTimeTokenReq, opts ...grpc.CallOption) (*CreateOneTimeTokenResp, error)
|
||||||
|
// CancelOneTimeToken 取消一次性使用
|
||||||
|
CancelOneTimeToken(ctx context.Context, in *CancelOneTimeTokenReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
defaultTokenService struct {
|
||||||
|
cli zrpc.Client
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
func NewTokenService(cli zrpc.Client) TokenService {
|
||||||
|
return &defaultTokenService{
|
||||||
|
cli: cli,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewToken 建立一個新的 Token,例如:AccessToken
|
||||||
|
func (m *defaultTokenService) NewToken(ctx context.Context, in *AuthorizationReq, opts ...grpc.CallOption) (*TokenResp, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.NewToken(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
|
||||||
|
func (m *defaultTokenService) RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.RefreshToken(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelToken 取消 Token,也包含他裡面的 One Time Toke
|
||||||
|
func (m *defaultTokenService) CancelToken(ctx context.Context, in *CancelTokenReq, opts ...grpc.CallOption) (*OKResp, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.CancelToken(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
||||||
|
func (m *defaultTokenService) CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.CancelTokenByUid(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelTokenByDeviceId 取消 Token
|
||||||
|
func (m *defaultTokenService) CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.CancelTokenByDeviceId(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidationToken 驗證這個 Token 有沒有效
|
||||||
|
func (m *defaultTokenService) ValidationToken(ctx context.Context, in *ValidationTokenReq, opts ...grpc.CallOption) (*ValidationTokenResp, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.ValidationToken(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
|
||||||
|
func (m *defaultTokenService) GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.GetUserTokensByDeviceId(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
|
||||||
|
func (m *defaultTokenService) GetUserTokensByUid(ctx context.Context, in *QueryTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.GetUserTokensByUid(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
||||||
|
func (m *defaultTokenService) NewOneTimeToken(ctx context.Context, in *CreateOneTimeTokenReq, opts ...grpc.CallOption) (*CreateOneTimeTokenResp, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.NewOneTimeToken(ctx, in, opts...)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelOneTimeToken 取消一次性使用
|
||||||
|
func (m *defaultTokenService) CancelOneTimeToken(ctx context.Context, in *CancelOneTimeTokenReq, opts ...grpc.CallOption) (*OKResp, error) {
|
||||||
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
|
return client.CancelOneTimeToken(ctx, in, opts...)
|
||||||
|
}
|
|
@ -68,7 +68,13 @@ message CancelTokenReq {
|
||||||
|
|
||||||
// CancelTokenReq 註銷這個 Token
|
// CancelTokenReq 註銷這個 Token
|
||||||
message DoTokenByUIDReq {
|
message DoTokenByUIDReq {
|
||||||
repeated string uid = 1;
|
repeated string ids = 1;
|
||||||
|
string uid = 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// QueryTokenByUIDReq 拿這個UID 找 Token
|
||||||
|
message QueryTokenByUIDReq {
|
||||||
|
string uid = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidationTokenReq 驗證這個 Token
|
// ValidationTokenReq 驗證這個 Token
|
||||||
|
@ -112,6 +118,10 @@ message DoTokenByDeviceIDReq {
|
||||||
}
|
}
|
||||||
|
|
||||||
message Tokens{
|
message Tokens{
|
||||||
|
repeated TokenResp token = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
message CancelOneTimeTokenReq {
|
||||||
repeated string token = 1;
|
repeated string token = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,23 +135,29 @@ service TokenService {
|
||||||
rpc RefreshToken(RefreshTokenReq) returns(RefreshTokenResp);
|
rpc RefreshToken(RefreshTokenReq) returns(RefreshTokenResp);
|
||||||
// CancelToken 取消 Token,也包含他裡面的 One Time Toke
|
// CancelToken 取消 Token,也包含他裡面的 One Time Toke
|
||||||
rpc CancelToken(CancelTokenReq) returns(OKResp);
|
rpc CancelToken(CancelTokenReq) returns(OKResp);
|
||||||
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
|
||||||
rpc CancelTokenByUid(DoTokenByUIDReq) returns(OKResp);
|
|
||||||
// CancelTokenByDeviceID 取消 Token
|
|
||||||
rpc CancelTokenByDeviceId(DoTokenByDeviceIDReq) returns(OKResp);
|
|
||||||
// ValidationToken 驗證這個 Token 有沒有效
|
// ValidationToken 驗證這個 Token 有沒有效
|
||||||
rpc ValidationToken(ValidationTokenReq) returns(ValidationTokenResp);
|
rpc ValidationToken(ValidationTokenReq) returns(ValidationTokenResp);
|
||||||
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens
|
// CancelTokens 取消 Token 從UID 視角,以及 token id 視角出發, UID 登出,底下所有 Device ID 也要登出, Token ID 登出, 所有 UID + Device 都要登出
|
||||||
|
rpc CancelTokens(DoTokenByUIDReq) returns(OKResp);
|
||||||
|
|
||||||
|
// CancelTokenByDeviceId 取消 Token, 從 Device 視角出發,可以選,登出這個Device 下所有 token ,登出這個Device 下指定token
|
||||||
|
rpc CancelTokenByDeviceId(DoTokenByDeviceIDReq) returns(OKResp);
|
||||||
|
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
|
||||||
rpc GetUserTokensByDeviceId(DoTokenByDeviceIDReq) returns(Tokens);
|
rpc GetUserTokensByDeviceId(DoTokenByDeviceIDReq) returns(Tokens);
|
||||||
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens
|
|
||||||
rpc GetUserTokensByUid(DoTokenByUIDReq) returns(Tokens);
|
|
||||||
|
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
|
||||||
|
rpc GetUserTokensByUid(QueryTokenByUIDReq) returns(Tokens);
|
||||||
|
|
||||||
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
||||||
rpc NewOneTimeToken(CreateOneTimeTokenReq) returns(CreateOneTimeTokenResp);
|
rpc NewOneTimeToken(CreateOneTimeTokenReq) returns(CreateOneTimeTokenResp);
|
||||||
// CancelOneTimeToken 取消一次性使用
|
// CancelOneTimeToken 取消一次性使用
|
||||||
rpc CancelOneTimeToken(CreateOneTimeTokenReq) returns(CreateOneTimeTokenResp);
|
rpc CancelOneTimeToken(CancelOneTimeTokenReq) returns(OKResp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//service Role_Service {}
|
service RoleService {
|
||||||
//
|
rpc Ping(OKResp) returns(OKResp);
|
||||||
//service Permission_Service {}
|
}
|
||||||
|
|
||||||
|
service PermissionService {}
|
|
@ -22,6 +22,7 @@ const (
|
||||||
const (
|
const (
|
||||||
RedisDelErrorCode = iota + 20
|
RedisDelErrorCode = iota + 20
|
||||||
RedisPipLineErrorCode
|
RedisPipLineErrorCode
|
||||||
|
RedisErrorCode
|
||||||
)
|
)
|
||||||
|
|
||||||
// TokenUnexpectedSigningErr 30001 Token 簽名錯誤
|
// TokenUnexpectedSigningErr 30001 Token 簽名錯誤
|
||||||
|
@ -53,5 +54,12 @@ func RedisDelError(msg string) *ers.Err {
|
||||||
func RedisPipLineError(msg string) *ers.Err {
|
func RedisPipLineError(msg string) *ers.Err {
|
||||||
// 看需要建立哪些 Metrics
|
// 看需要建立哪些 Metrics
|
||||||
mts.AppErrorMetrics.AddFailure("redis", "pip_line_error")
|
mts.AppErrorMetrics.AddFailure("redis", "pip_line_error")
|
||||||
return ers.NewErr(code.CloudEPPermission, code.CatInput, TokenClaimErrorCode, msg)
|
return ers.NewErr(code.CloudEPPermission, code.CatInput, RedisPipLineErrorCode, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
// RedisError 30022 Redis 錯誤
|
||||||
|
func RedisError(msg string) *ers.Err {
|
||||||
|
// 看需要建立哪些 Metrics
|
||||||
|
mts.AppErrorMetrics.AddFailure("redis", "error")
|
||||||
|
return ers.NewErr(code.CloudEPPermission, code.CatInput, RedisErrorCode, msg)
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,30 @@ package repository
|
||||||
import (
|
import (
|
||||||
"ark-permission/internal/entity"
|
"ark-permission/internal/entity"
|
||||||
"context"
|
"context"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type TokenRepository interface {
|
type TokenRepository interface {
|
||||||
Create(ctx context.Context, token entity.Token) error
|
Create(ctx context.Context, token entity.Token) error
|
||||||
GetByAccess(ctx context.Context, id string) (entity.Token, error)
|
DeleteOneTimeToken(ctx context.Context, ids []string, tokens []entity.Token) error
|
||||||
|
CreateOneTimeToken(ctx context.Context, key string, ticket entity.Ticket, dt time.Duration) error
|
||||||
|
GetByRefresh(ctx context.Context, refreshToken string) (entity.Token, error)
|
||||||
|
|
||||||
|
GetAccessTokenByID(ctx context.Context, id string) (entity.Token, error)
|
||||||
|
GetAccessTokensByUID(ctx context.Context, uid string) ([]entity.Token, error)
|
||||||
|
GetAccessTokenCountByUID(uid string) (int, error)
|
||||||
|
GetAccessTokensByDeviceID(ctx context.Context, deviceID string) ([]entity.Token, error)
|
||||||
|
GetAccessTokenCountByDeviceID(deviceID string) (int, error)
|
||||||
|
|
||||||
Delete(ctx context.Context, token entity.Token) error
|
Delete(ctx context.Context, token entity.Token) error
|
||||||
|
DeleteAccessTokenByID(ctx context.Context, id string) error
|
||||||
|
DeleteAccessTokensByUID(ctx context.Context, uid string) error
|
||||||
|
DeleteAccessTokensByDeviceID(ctx context.Context, deviceID string) error
|
||||||
|
DeleteAccessTokenByDeviceIDAndUID(ctx context.Context, deviceID, uid string) error
|
||||||
|
DeleteUIDToken(ctx context.Context, uid string, ids []string) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeviceToken struct {
|
||||||
|
DeviceID string
|
||||||
|
TokenID string
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,6 @@ func (t *Token) IsExpires() bool {
|
||||||
type UIDToken map[string]int64
|
type UIDToken map[string]int64
|
||||||
|
|
||||||
type Ticket struct {
|
type Ticket struct {
|
||||||
Data interface{} `json:"data"`
|
Data any `json:"data"`
|
||||||
Token Token `json:"token"`
|
Token Token `json:"token"`
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,31 +0,0 @@
|
||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
|
||||||
"ark-permission/internal/svc"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type GetUserTokensByUidLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewGetUserTokensByUidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserTokensByUidLogic {
|
|
||||||
return &GetUserTokensByUidLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens
|
|
||||||
func (l *GetUserTokensByUidLogic) GetUserTokensByUid(in *permission.DoTokenByUIDReq) (*permission.Tokens, error) {
|
|
||||||
// todo: add your logic here and delete this line
|
|
||||||
|
|
||||||
return &permission.Tokens{}, nil
|
|
||||||
}
|
|
|
@ -1,31 +0,0 @@
|
||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
|
||||||
"ark-permission/internal/svc"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type NewOneTimeTokenLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewNewOneTimeTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NewOneTimeTokenLogic {
|
|
||||||
return &NewOneTimeTokenLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
|
||||||
func (l *NewOneTimeTokenLogic) NewOneTimeToken(in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
|
|
||||||
// todo: add your logic here and delete this line
|
|
||||||
|
|
||||||
return &permission.CreateOneTimeTokenResp{}, nil
|
|
||||||
}
|
|
|
@ -1,30 +0,0 @@
|
||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
|
||||||
"ark-permission/internal/svc"
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type RefreshTokenLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewRefreshTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RefreshTokenLogic {
|
|
||||||
return &RefreshTokenLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
|
|
||||||
func (l *RefreshTokenLogic) RefreshToken(in *permission.RefreshTokenReq) (*permission.RefreshTokenResp, error) {
|
|
||||||
// todo: add your logic here and delete this line
|
|
||||||
|
|
||||||
return &permission.RefreshTokenResp{}, nil
|
|
||||||
}
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
package roleservicelogic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PingLogic struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPingLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PingLogic {
|
||||||
|
return &PingLogic{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l *PingLogic) Ping(in *permission.OKResp) (*permission.OKResp, error) {
|
||||||
|
// todo: add your logic here and delete this line
|
||||||
|
|
||||||
|
return &permission.OKResp{}, nil
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
ers "code.30cm.net/wanderland/library-go/errors"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
@ -23,9 +24,23 @@ func NewCancelOneTimeTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelOneTimeToken 取消一次性使用
|
type cancelOneTimeTokenReq struct {
|
||||||
func (l *CancelOneTimeTokenLogic) CancelOneTimeToken(in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
|
Token []string `json:"token" validate:"required"`
|
||||||
// todo: add your logic here and delete this line
|
}
|
||||||
|
|
||||||
return &permission.CreateOneTimeTokenResp{}, nil
|
// CancelOneTimeToken 取消一次性使用
|
||||||
|
func (l *CancelOneTimeTokenLogic) CancelOneTimeToken(in *permission.CancelOneTimeTokenReq) (*permission.OKResp, error) {
|
||||||
|
// 驗證所需
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&cancelOneTimeTokenReq{
|
||||||
|
Token: in.GetToken(),
|
||||||
|
}); err != nil {
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err := l.svcCtx.TokenRedisRepo.DeleteOneTimeToken(l.ctx, in.GetToken(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &permission.OKResp{}, nil
|
||||||
}
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
@ -23,7 +23,7 @@ func NewCancelTokenByDeviceIdLogic(ctx context.Context, svcCtx *svc.ServiceConte
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelTokenByDeviceID 取消 Token
|
// CancelTokenByDeviceId 取消 Token
|
||||||
func (l *CancelTokenByDeviceIdLogic) CancelTokenByDeviceId(in *permission.DoTokenByDeviceIDReq) (*permission.OKResp, error) {
|
func (l *CancelTokenByDeviceIdLogic) CancelTokenByDeviceId(in *permission.DoTokenByDeviceIDReq) (*permission.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// todo: add your logic here and delete this line
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
ers "code.30cm.net/wanderland/library-go/errors"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
@ -23,9 +24,25 @@ func NewCancelTokenByUidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
type deleteByTokenIDs struct {
|
||||||
|
UID string `json:"uid" binding:"required"`
|
||||||
|
IDs []string `json:"ids" binding:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
||||||
func (l *CancelTokenByUidLogic) CancelTokenByUid(in *permission.DoTokenByUIDReq) (*permission.OKResp, error) {
|
func (l *CancelTokenByUidLogic) CancelTokenByUid(in *permission.DoTokenByUIDReq) (*permission.OKResp, error) {
|
||||||
// todo: add your logic here and delete this line
|
// 驗證所需
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&deleteByTokenIDs{
|
||||||
|
UID: in.GetUid(),
|
||||||
|
IDs: in.GetIds(),
|
||||||
|
}); err != nil {
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
err := l.svcCtx.TokenRedisRepo.DeleteUIDToken(l.ctx, in.GetUid(), in.GetIds())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
return &permission.OKResp{}, nil
|
return &permission.OKResp{}, nil
|
||||||
}
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"ark-permission/gen_result/pb/permission"
|
|
||||||
"ark-permission/internal/svc"
|
|
||||||
ers "code.30cm.net/wanderland/library-go/errors"
|
ers "code.30cm.net/wanderland/library-go/errors"
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,11 +1,9 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
|
||||||
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
"ark-permission/gen_result/pb/permission"
|
||||||
"ark-permission/internal/svc"
|
"ark-permission/internal/svc"
|
||||||
|
"context"
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -23,9 +21,23 @@ func NewGetUserTokensByDeviceIdLogic(ctx context.Context, svcCtx *svc.ServiceCon
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens
|
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
|
||||||
func (l *GetUserTokensByDeviceIdLogic) GetUserTokensByDeviceId(in *permission.DoTokenByDeviceIDReq) (*permission.Tokens, error) {
|
func (l *GetUserTokensByDeviceIdLogic) GetUserTokensByDeviceId(in *permission.DoTokenByDeviceIDReq) (*permission.Tokens, error) {
|
||||||
// todo: add your logic here and delete this line
|
|
||||||
|
// ids, err := l.svcCtx.TokenRedisRepo.GetAccessTokensByDeviceID(l.ctx, "")
|
||||||
|
// if err != nil {
|
||||||
|
// return nil, error
|
||||||
|
// }
|
||||||
|
|
||||||
|
// tokenIDs := make([]usecase.DeviceToken, 0, len(ids))
|
||||||
|
// for _, v := range ids {
|
||||||
|
// tokenIDs = append(tokenIDs, usecase.DeviceToken{
|
||||||
|
// DeviceID: v.DeviceID,
|
||||||
|
// TokenID: v.TokenID,
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return tokenIDs, nil
|
||||||
|
|
||||||
return &permission.Tokens{}, nil
|
return &permission.Tokens{}, nil
|
||||||
}
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package tokenservicelogic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/domain"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
ers "code.30cm.net/wanderland/library-go/errors"
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type GetUserTokensByUidLogic struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewGetUserTokensByUidLogic(ctx context.Context, svcCtx *svc.ServiceContext) *GetUserTokensByUidLogic {
|
||||||
|
return &GetUserTokensByUidLogic{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type getUserTokensByUidReq struct {
|
||||||
|
UID string `json:"uid" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
|
||||||
|
func (l *GetUserTokensByUidLogic) GetUserTokensByUid(in *permission.QueryTokenByUIDReq) (*permission.Tokens, error) {
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&getUserTokensByUidReq{
|
||||||
|
UID: in.GetUid(),
|
||||||
|
}); err != nil {
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
uidTokens, err := l.svcCtx.TokenRedisRepo.GetAccessTokensByUID(l.ctx, in.GetUid())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
tokens := make([]*permission.TokenResp, 0, len(uidTokens))
|
||||||
|
for _, v := range uidTokens {
|
||||||
|
tokens = append(tokens, &permission.TokenResp{
|
||||||
|
AccessToken: v.AccessToken,
|
||||||
|
TokenType: domain.TokenTypeBearer,
|
||||||
|
ExpiresIn: int32(v.ExpiresIn),
|
||||||
|
RefreshToken: v.RefreshToken,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
return &permission.Tokens{
|
||||||
|
Token: tokens,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -0,0 +1,69 @@
|
||||||
|
package tokenservicelogic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ark-permission/internal/domain"
|
||||||
|
"ark-permission/internal/entity"
|
||||||
|
ers "code.30cm.net/wanderland/library-go/errors"
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type NewOneTimeTokenLogic struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewNewOneTimeTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *NewOneTimeTokenLogic {
|
||||||
|
return &NewOneTimeTokenLogic{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
||||||
|
func (l *NewOneTimeTokenLogic) NewOneTimeToken(in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
|
||||||
|
// 驗證所需
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&refreshTokenReq{
|
||||||
|
Token: in.GetToken(),
|
||||||
|
}); err != nil {
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
// 驗證Token
|
||||||
|
claims, err := parseClaims(l.ctx, in.GetToken(), l.svcCtx.Config.Token.Secret)
|
||||||
|
if err != nil {
|
||||||
|
logx.WithCallerSkip(1).WithFields(
|
||||||
|
logx.Field("func", "parseClaims"),
|
||||||
|
).Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := l.svcCtx.TokenRedisRepo.GetByAccess(l.ctx, claims.ID())
|
||||||
|
if err != nil {
|
||||||
|
logx.WithCallerSkip(1).WithFields(
|
||||||
|
logx.Field("func", "TokenRedisRepo.GetByAccess"),
|
||||||
|
logx.Field("claims", claims),
|
||||||
|
).Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
oneTimeToken := generateRefreshToken(in.GetToken())
|
||||||
|
key := domain.TicketKeyPrefix + oneTimeToken
|
||||||
|
if err = l.svcCtx.TokenRedisRepo.CreateOneTimeToken(l.ctx, key, entity.Ticket{
|
||||||
|
Data: claims,
|
||||||
|
Token: token,
|
||||||
|
}, time.Minute); err != nil {
|
||||||
|
return &permission.CreateOneTimeTokenResp{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &permission.CreateOneTimeTokenResp{
|
||||||
|
OneTimeToken: oneTimeToken,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -1,15 +1,16 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"ark-permission/gen_result/pb/permission"
|
|
||||||
"ark-permission/internal/domain"
|
"ark-permission/internal/domain"
|
||||||
"ark-permission/internal/entity"
|
"ark-permission/internal/entity"
|
||||||
"ark-permission/internal/svc"
|
|
||||||
ers "code.30cm.net/wanderland/library-go/errors"
|
ers "code.30cm.net/wanderland/library-go/errors"
|
||||||
"context"
|
"context"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -37,9 +38,6 @@ type authorizationReq struct {
|
||||||
IsRefreshToken bool `json:"is_refresh_token"`
|
IsRefreshToken bool `json:"is_refresh_token"`
|
||||||
}
|
}
|
||||||
|
|
||||||
var generateAccessTokenFunc = generateAccessToken
|
|
||||||
var generateRefreshTokenFunc = generateRefreshToken
|
|
||||||
|
|
||||||
// NewToken 建立一個新的 Token,例如:AccessToken
|
// NewToken 建立一個新的 Token,例如:AccessToken
|
||||||
func (l *NewTokenLogic) NewToken(in *permission.AuthorizationReq) (*permission.TokenResp, error) {
|
func (l *NewTokenLogic) NewToken(in *permission.AuthorizationReq) (*permission.TokenResp, error) {
|
||||||
// 驗證所需
|
// 驗證所需
|
||||||
|
@ -55,13 +53,23 @@ func (l *NewTokenLogic) NewToken(in *permission.AuthorizationReq) (*permission.T
|
||||||
expires := int(in.GetExpires())
|
expires := int(in.GetExpires())
|
||||||
refreshExpires := int(in.GetExpires())
|
refreshExpires := int(in.GetExpires())
|
||||||
if expires <= 0 {
|
if expires <= 0 {
|
||||||
expires = int(l.svcCtx.Config.Token.Expired.Seconds())
|
// 將時間加上 300 秒
|
||||||
|
sec := time.Duration(l.svcCtx.Config.Token.Expired.Seconds()) * time.Second
|
||||||
|
newTime := now.Add(sec)
|
||||||
|
// 獲取 Unix 時間戳
|
||||||
|
timestamp := newTime.Unix()
|
||||||
|
expires = int(timestamp)
|
||||||
refreshExpires = expires
|
refreshExpires = expires
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果這是一個 Refresh Token 過期時間要比普通的Token 長
|
// 如果這是一個 Refresh Token 過期時間要比普通的Token 長
|
||||||
if in.GetIsRefreshToken() {
|
if in.GetIsRefreshToken() {
|
||||||
refreshExpires = int(l.svcCtx.Config.Token.RefreshExpires.Seconds())
|
// 將時間加上 300 秒
|
||||||
|
sec := time.Duration(l.svcCtx.Config.Token.RefreshExpires.Seconds()) * time.Second
|
||||||
|
newTime := now.Add(sec)
|
||||||
|
// 獲取 Unix 時間戳
|
||||||
|
timestamp := newTime.Unix()
|
||||||
|
refreshExpires = int(timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
token := entity.Token{
|
token := entity.Token{
|
|
@ -1,4 +1,4 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"ark-permission/internal/entity"
|
"ark-permission/internal/entity"
|
|
@ -0,0 +1,133 @@
|
||||||
|
package tokenservicelogic
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ark-permission/internal/domain"
|
||||||
|
"ark-permission/internal/entity"
|
||||||
|
ers "code.30cm.net/wanderland/library-go/errors"
|
||||||
|
"context"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RefreshTokenLogic struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRefreshTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RefreshTokenLogic {
|
||||||
|
return &RefreshTokenLogic{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type refreshReq struct {
|
||||||
|
RefreshToken string `json:"grant_type" validate:"required"`
|
||||||
|
DeviceID string `json:"device_id" validate:"required"`
|
||||||
|
Scope string `json:"scope" validate:"required"`
|
||||||
|
Expires int64 `json:"expires" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
|
||||||
|
func (l *RefreshTokenLogic) RefreshToken(in *permission.RefreshTokenReq) (*permission.RefreshTokenResp, error) {
|
||||||
|
// 驗證所需
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&refreshReq{
|
||||||
|
RefreshToken: in.GetToken(),
|
||||||
|
Scope: in.GetScope(),
|
||||||
|
DeviceID: in.GetDeviceId(),
|
||||||
|
Expires: in.GetExpires(),
|
||||||
|
}); err != nil {
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
// step 1 拿看看有沒有這個 refresh token
|
||||||
|
token, err := l.svcCtx.TokenRedisRepo.GetByRefresh(l.ctx, in.Token)
|
||||||
|
if err != nil {
|
||||||
|
logx.WithCallerSkip(1).WithFields(
|
||||||
|
logx.Field("func", "TokenRedisRepo.GetByRefresh"),
|
||||||
|
logx.Field("req", in),
|
||||||
|
).Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
// 拿到之後替換掉時間以及 refresh token
|
||||||
|
// refreshToken 建立
|
||||||
|
now := time.Now().UTC()
|
||||||
|
sec := time.Duration(l.svcCtx.Config.Token.RefreshExpires.Seconds()) * time.Second
|
||||||
|
newTime := now.Add(sec)
|
||||||
|
// 獲取 Unix 時間戳
|
||||||
|
timestamp := newTime.Unix()
|
||||||
|
refreshExpires := int(timestamp)
|
||||||
|
expires := int(in.GetExpires())
|
||||||
|
if expires <= 0 {
|
||||||
|
// 將時間加上 300 秒
|
||||||
|
sec := time.Duration(l.svcCtx.Config.Token.Expired.Seconds()) * time.Second
|
||||||
|
newTime := now.Add(sec)
|
||||||
|
// 獲取 Unix 時間戳
|
||||||
|
timestamp := newTime.Unix()
|
||||||
|
expires = int(timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
newToken := entity.Token{
|
||||||
|
ID: token.ID,
|
||||||
|
UID: token.UID,
|
||||||
|
DeviceID: in.GetDeviceId(),
|
||||||
|
ExpiresIn: expires,
|
||||||
|
RefreshExpiresIn: refreshExpires,
|
||||||
|
AccessCreateAt: now,
|
||||||
|
RefreshCreateAt: now,
|
||||||
|
}
|
||||||
|
|
||||||
|
claims := claims(map[string]string{
|
||||||
|
"uid": token.UID,
|
||||||
|
})
|
||||||
|
claims.SetRole(domain.DefaultRole)
|
||||||
|
claims.SetID(token.ID)
|
||||||
|
claims.SetScope(in.GetScope())
|
||||||
|
claims.UID()
|
||||||
|
|
||||||
|
if in.GetDeviceId() != "" {
|
||||||
|
claims.SetDeviceID(in.GetDeviceId())
|
||||||
|
}
|
||||||
|
|
||||||
|
newToken.AccessToken, err = generateAccessTokenFunc(newToken, claims, l.svcCtx.Config.Token.Secret)
|
||||||
|
if err != nil {
|
||||||
|
logx.WithCallerSkip(1).WithFields(
|
||||||
|
logx.Field("func", "generateAccessTokenFunc"),
|
||||||
|
logx.Field("claims", claims),
|
||||||
|
).Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
newToken.RefreshToken = generateRefreshTokenFunc(newToken.AccessToken)
|
||||||
|
|
||||||
|
// 刪除掉舊的 token
|
||||||
|
err = l.svcCtx.TokenRedisRepo.Delete(l.ctx, token)
|
||||||
|
if err != nil {
|
||||||
|
logx.WithCallerSkip(1).WithFields(
|
||||||
|
logx.Field("func", "TokenRedisRepo.Delete"),
|
||||||
|
logx.Field("req", token),
|
||||||
|
).Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = l.svcCtx.TokenRedisRepo.Create(l.ctx, newToken)
|
||||||
|
if err != nil {
|
||||||
|
logx.WithCallerSkip(1).WithFields(
|
||||||
|
logx.Field("func", "TokenRedisRepo.Create"),
|
||||||
|
logx.Field("token", token),
|
||||||
|
).Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &permission.RefreshTokenResp{
|
||||||
|
Token: newToken.AccessToken,
|
||||||
|
OneTimeToken: newToken.RefreshToken,
|
||||||
|
ExpiresIn: int64(expires),
|
||||||
|
TokenType: domain.TokenTypeBearer,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
type claims map[string]string
|
type claims map[string]string
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package logic
|
package tokenservicelogic
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"ark-permission/internal/domain"
|
"ark-permission/internal/domain"
|
||||||
|
@ -12,6 +12,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var generateAccessTokenFunc = generateAccessToken
|
||||||
|
var generateRefreshTokenFunc = generateRefreshToken
|
||||||
|
|
||||||
func generateAccessToken(token entity.Token, data any, sign string) (string, error) {
|
func generateAccessToken(token entity.Token, data any, sign string) (string, error) {
|
||||||
claim := entity.Claims{
|
claim := entity.Claims{
|
||||||
Data: data,
|
Data: data,
|
||||||
|
@ -40,7 +43,7 @@ func generateRefreshToken(accessToken string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseClaims(ctx context.Context, accessToken string, secret string) (claims, error) {
|
func parseClaims(ctx context.Context, accessToken string, secret string) (claims, error) {
|
||||||
claimMap, err := parseToken(ctx, accessToken, secret)
|
claimMap, err := parseToken(accessToken, secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return claims{}, err
|
return claims{}, err
|
||||||
}
|
}
|
||||||
|
@ -54,7 +57,7 @@ func parseClaims(ctx context.Context, accessToken string, secret string) (claims
|
||||||
return nil, domain.TokenClaimError("get data from claim map error")
|
return nil, domain.TokenClaimError("get data from claim map error")
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseToken(ctx context.Context, accessToken string, secret string) (jwt.MapClaims, error) {
|
func parseToken(accessToken string, secret string) (jwt.MapClaims, error) {
|
||||||
token, err := jwt.Parse(accessToken, func(token *jwt.Token) (any, error) {
|
token, err := jwt.Parse(accessToken, func(token *jwt.Token) (any, error) {
|
||||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||||
return nil, domain.TokenUnexpectedSigningErr(fmt.Sprintf("token unexpected signing method: %v", token.Header["alg"]))
|
return nil, domain.TokenUnexpectedSigningErr(fmt.Sprintf("token unexpected signing method: %v", token.Header["alg"]))
|
|
@ -0,0 +1,71 @@
|
||||||
|
package tokenservicelogic
|
||||||
|
|
||||||
|
import (
|
||||||
|
ers "code.30cm.net/wanderland/library-go/errors"
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
|
||||||
|
"github.com/zeromicro/go-zero/core/logx"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ValidationTokenLogic struct {
|
||||||
|
ctx context.Context
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
logx.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewValidationTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ValidationTokenLogic {
|
||||||
|
return &ValidationTokenLogic{
|
||||||
|
ctx: ctx,
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
Logger: logx.WithContext(ctx),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type refreshTokenReq struct {
|
||||||
|
Token string `json:"token" validate:"required"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidationToken 驗證這個 Token 有沒有效
|
||||||
|
func (l *ValidationTokenLogic) ValidationToken(in *permission.ValidationTokenReq) (*permission.ValidationTokenResp, error) {
|
||||||
|
// 驗證所需
|
||||||
|
if err := l.svcCtx.Validate.ValidateAll(&refreshTokenReq{
|
||||||
|
Token: in.GetToken(),
|
||||||
|
}); err != nil {
|
||||||
|
return nil, ers.InvalidFormat(err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
claims, err := parseClaims(l.ctx, in.GetToken(), l.svcCtx.Config.Token.Secret)
|
||||||
|
if err != nil {
|
||||||
|
logx.WithCallerSkip(1).WithFields(
|
||||||
|
logx.Field("func", "parseClaims"),
|
||||||
|
).Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
token, err := l.svcCtx.TokenRedisRepo.GetByAccess(l.ctx, claims.ID())
|
||||||
|
if err != nil {
|
||||||
|
logx.WithCallerSkip(1).WithFields(
|
||||||
|
logx.Field("func", "TokenRedisRepo.GetByAccess"),
|
||||||
|
logx.Field("claims", claims),
|
||||||
|
).Error(err.Error())
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &permission.ValidationTokenResp{
|
||||||
|
Token: &permission.Token{
|
||||||
|
Id: token.ID,
|
||||||
|
Uid: token.UID,
|
||||||
|
DeviceId: token.DeviceID,
|
||||||
|
AccessCreateAt: token.AccessCreateAt.Unix(),
|
||||||
|
AccessToken: token.AccessToken,
|
||||||
|
ExpiresIn: int32(token.ExpiresIn),
|
||||||
|
RefreshToken: token.RefreshToken,
|
||||||
|
RefreshExpiresIn: int32(token.RefreshExpiresIn),
|
||||||
|
RefreshCreateAt: token.RefreshCreateAt.Unix(),
|
||||||
|
},
|
||||||
|
Data: claims,
|
||||||
|
}, nil
|
||||||
|
}
|
|
@ -1,31 +0,0 @@
|
||||||
package logic
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
|
||||||
"ark-permission/internal/svc"
|
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/logx"
|
|
||||||
)
|
|
||||||
|
|
||||||
type ValidationTokenLogic struct {
|
|
||||||
ctx context.Context
|
|
||||||
svcCtx *svc.ServiceContext
|
|
||||||
logx.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewValidationTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *ValidationTokenLogic {
|
|
||||||
return &ValidationTokenLogic{
|
|
||||||
ctx: ctx,
|
|
||||||
svcCtx: svcCtx,
|
|
||||||
Logger: logx.WithContext(ctx),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ValidationToken 驗證這個 Token 有沒有效
|
|
||||||
func (l *ValidationTokenLogic) ValidationToken(in *permission.ValidationTokenReq) (*permission.ValidationTokenResp, error) {
|
|
||||||
// todo: add your logic here and delete this line
|
|
||||||
|
|
||||||
return &permission.ValidationTokenResp{}, nil
|
|
||||||
}
|
|
|
@ -22,6 +22,41 @@ type tokenRepository struct {
|
||||||
store *redis.Redis
|
store *redis.Redis
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) GetAccessTokenCountByUID(uid string) (int, error) {
|
||||||
|
// TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) GetAccessTokensByDeviceID(ctx context.Context, deviceID string) ([]entity.Token, error) {
|
||||||
|
// TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) GetAccessTokenCountByDeviceID(deviceID string) (int, error) {
|
||||||
|
// TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) DeleteAccessTokenByID(ctx context.Context, id string) error {
|
||||||
|
// TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) DeleteAccessTokensByUID(ctx context.Context, uid string) error {
|
||||||
|
// TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) DeleteAccessTokensByDeviceID(ctx context.Context, deviceID string) error {
|
||||||
|
// TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) DeleteAccessTokenByDeviceIDAndUID(ctx context.Context, deviceID, uid string) error {
|
||||||
|
// TODO implement me
|
||||||
|
panic("implement me")
|
||||||
|
}
|
||||||
|
|
||||||
func NewTokenRepository(param TokenRepositoryParam) repository.TokenRepository {
|
func NewTokenRepository(param TokenRepositoryParam) repository.TokenRepository {
|
||||||
return &tokenRepository{
|
return &tokenRepository{
|
||||||
store: param.Store,
|
store: param.Store,
|
||||||
|
@ -62,10 +97,185 @@ func (t *tokenRepository) Create(ctx context.Context, token entity.Token) error
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *tokenRepository) GetByAccess(_ context.Context, id string) (entity.Token, error) {
|
// // GetAccessTokensByDeviceID 透過 Device ID 得到目前未過期的token
|
||||||
|
// func (t *tokenRepository) GetAccessTokensByDeviceID(ctx context.Context, uid string) ([]repository.DeviceToken, error) {
|
||||||
|
// data, err := t.store.Hgetall(domain.DeviceTokenRedisKey.With(uid).ToString())
|
||||||
|
// if err != nil {
|
||||||
|
// if errors.Is(err, redis.Nil) {
|
||||||
|
// return nil, nil
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// return nil, domain.RedisError(fmt.Sprintf("tokenRepository.GetAccessTokensByDeviceID store.HGetAll Device Token error: %v", err.Error()))
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// ids := make([]repository.DeviceToken, 0, len(data))
|
||||||
|
// for deviceID, id := range data {
|
||||||
|
// ids = append(ids, repository.DeviceToken{
|
||||||
|
// DeviceID: deviceID,
|
||||||
|
//
|
||||||
|
// // e0a4f824-41db-4eb2-8e5a-d96966ea1d56-1698083859
|
||||||
|
// // -11是因為id組成最後11位數是-跟時間戳記
|
||||||
|
// TokenID: id[:len(id)-11],
|
||||||
|
// })
|
||||||
|
// }
|
||||||
|
// return ids, nil
|
||||||
|
// }
|
||||||
|
|
||||||
|
// GetAccessTokensByUID 透過 uid 得到目前未過期的 token
|
||||||
|
func (t *tokenRepository) GetAccessTokensByUID(ctx context.Context, uid string) ([]entity.Token, error) {
|
||||||
|
utKeys, err := t.store.Get(domain.GetUIDTokenRedisKey(uid))
|
||||||
|
if err != nil {
|
||||||
|
// 沒有就視為回空
|
||||||
|
if errors.Is(err, redis.Nil) {
|
||||||
|
return nil, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil, domain.RedisError(fmt.Sprintf("tokenRepository.GetAccessTokensByUID store.Get GetUIDTokenRedisKey error: %v", err.Error()))
|
||||||
|
}
|
||||||
|
|
||||||
|
uidTokens := make(entity.UIDToken)
|
||||||
|
err = json.Unmarshal([]byte(utKeys), &uidTokens)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ers.ArkInternal(fmt.Sprintf("tokenRepository.GetAccessTokensByUID json.Unmarshal GetUIDTokenRedisKey error: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
var tokens []entity.Token
|
||||||
|
var deleteToken []string
|
||||||
|
for id, token := range uidTokens {
|
||||||
|
if token < now {
|
||||||
|
deleteToken = append(deleteToken, id)
|
||||||
|
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
tk, err := t.store.Get(domain.GetAccessTokenRedisKey(id))
|
||||||
|
if err == nil {
|
||||||
|
item := entity.Token{}
|
||||||
|
err = json.Unmarshal([]byte(tk), &item)
|
||||||
|
if err != nil {
|
||||||
|
return nil, ers.ArkInternal(fmt.Sprintf("tokenRepository.GetAccessTokensByUID json.Unmarshal GetUIDTokenRedisKey error: %v", err))
|
||||||
|
}
|
||||||
|
tokens = append(tokens, item)
|
||||||
|
}
|
||||||
|
|
||||||
|
if errors.Is(err, redis.Nil) {
|
||||||
|
deleteToken = append(deleteToken, id)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(deleteToken) > 0 {
|
||||||
|
// 如果失敗也沒關係,其他get method撈取時會在判斷是否過期或存在
|
||||||
|
_ = t.DeleteUIDToken(ctx, uid, deleteToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) DeleteUIDToken(ctx context.Context, uid string, ids []string) error {
|
||||||
|
uidTokens := make(entity.UIDToken)
|
||||||
|
tokenKeys, err := t.store.Get(domain.GetUIDTokenRedisKey(uid))
|
||||||
|
if err != nil {
|
||||||
|
if !errors.Is(err, redis.Nil) {
|
||||||
|
return fmt.Errorf("tx.get GetDeviceTokenRedisKey error: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if tokenKeys != "" {
|
||||||
|
err = json.Unmarshal([]byte(tokenKeys), &uidTokens)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("json.Unmarshal GetDeviceTokenRedisKey error: %w", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
now := time.Now().Unix()
|
||||||
|
for k, t := range uidTokens {
|
||||||
|
// 到期就刪除
|
||||||
|
if t < now {
|
||||||
|
delete(uidTokens, k)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, id := range ids {
|
||||||
|
delete(uidTokens, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
b, err := json.Marshal(uidTokens)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("json.Marshal UIDToken error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = t.store.SetnxEx(domain.GetUIDTokenRedisKey(uid), string(b), 86400*30)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("tx.set GetUIDTokenRedisKey error: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) GetAccessTokenByID(_ context.Context, id string) (entity.Token, error) {
|
||||||
return t.get(domain.GetAccessTokenRedisKey(id))
|
return t.get(domain.GetAccessTokenRedisKey(id))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) GetByRefresh(ctx context.Context, refreshToken string) (entity.Token, error) {
|
||||||
|
id, err := t.store.Get(domain.RefreshTokenRedisKey.With(refreshToken).ToString())
|
||||||
|
if err != nil {
|
||||||
|
return entity.Token{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if errors.Is(err, redis.Nil) || id == "" {
|
||||||
|
return entity.Token{}, ers.ResourceNotFound("token key not found in redis", domain.RefreshTokenRedisKey.With(refreshToken).ToString())
|
||||||
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return entity.Token{}, ers.ArkInternal(fmt.Sprintf("store.GetByRefresh refresh token error: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return t.GetAccessTokenByID(ctx, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) DeleteOneTimeToken(ctx context.Context, ids []string, tokens []entity.Token) error {
|
||||||
|
err := t.store.Pipelined(func(tx redis.Pipeliner) error {
|
||||||
|
keys := make([]string, 0, len(ids)+len(tokens))
|
||||||
|
|
||||||
|
for _, id := range ids {
|
||||||
|
keys = append(keys, domain.RefreshTokenRedisKey.With(id).ToString())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, token := range tokens {
|
||||||
|
keys = append(keys, domain.RefreshTokenRedisKey.With(token.RefreshToken).ToString())
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, key := range keys {
|
||||||
|
if err := tx.Del(ctx, key).Err(); err != nil {
|
||||||
|
return domain.RedisDelError(fmt.Sprintf("store.Del key error: %v", err))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return domain.RedisPipLineError(fmt.Sprintf("store.Pipelined error: %v", err))
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (t *tokenRepository) CreateOneTimeToken(ctx context.Context, key string, ticket entity.Ticket, expires time.Duration) error {
|
||||||
|
body, err := json.Marshal(ticket)
|
||||||
|
if err != nil {
|
||||||
|
return ers.InvalidFormat("CreateOneTimeToken json.Marshal error:", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = t.store.SetnxEx(domain.GetTicketRedisKey(key), string(body), int(expires.Seconds()))
|
||||||
|
if err != nil {
|
||||||
|
return ers.DBError("CreateOneTimeToken store.set error:", err.Error())
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (t *tokenRepository) Delete(ctx context.Context, token entity.Token) error {
|
func (t *tokenRepository) Delete(ctx context.Context, token entity.Token) error {
|
||||||
err := t.store.Pipelined(func(tx redis.Pipeliner) error {
|
err := t.store.Pipelined(func(tx redis.Pipeliner) error {
|
||||||
keys := []string{
|
keys := []string{
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// Source: permission.proto
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PermissionServiceServer struct {
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
permission.UnimplementedPermissionServiceServer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewPermissionServiceServer(svcCtx *svc.ServiceContext) *PermissionServiceServer {
|
||||||
|
return &PermissionServiceServer{
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Code generated by goctl. DO NOT EDIT.
|
||||||
|
// Source: permission.proto
|
||||||
|
|
||||||
|
package server
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"ark-permission/gen_result/pb/permission"
|
||||||
|
"ark-permission/internal/logic/roleservice"
|
||||||
|
"ark-permission/internal/svc"
|
||||||
|
)
|
||||||
|
|
||||||
|
type RoleServiceServer struct {
|
||||||
|
svcCtx *svc.ServiceContext
|
||||||
|
permission.UnimplementedRoleServiceServer
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewRoleServiceServer(svcCtx *svc.ServiceContext) *RoleServiceServer {
|
||||||
|
return &RoleServiceServer{
|
||||||
|
svcCtx: svcCtx,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *RoleServiceServer) Ping(ctx context.Context, in *permission.OKResp) (*permission.OKResp, error) {
|
||||||
|
l := roleservicelogic.NewPingLogic(ctx, s.svcCtx)
|
||||||
|
return l.Ping(in)
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
"ark-permission/gen_result/pb/permission"
|
||||||
"ark-permission/internal/logic"
|
"ark-permission/internal/logic/tokenservice"
|
||||||
"ark-permission/internal/svc"
|
"ark-permission/internal/svc"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -24,60 +24,60 @@ func NewTokenServiceServer(svcCtx *svc.ServiceContext) *TokenServiceServer {
|
||||||
|
|
||||||
// NewToken 建立一個新的 Token,例如:AccessToken
|
// NewToken 建立一個新的 Token,例如:AccessToken
|
||||||
func (s *TokenServiceServer) NewToken(ctx context.Context, in *permission.AuthorizationReq) (*permission.TokenResp, error) {
|
func (s *TokenServiceServer) NewToken(ctx context.Context, in *permission.AuthorizationReq) (*permission.TokenResp, error) {
|
||||||
l := logic.NewNewTokenLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewNewTokenLogic(ctx, s.svcCtx)
|
||||||
return l.NewToken(in)
|
return l.NewToken(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
|
// RefreshToken 更新目前的token 以及裡面包含的一次性 Token
|
||||||
func (s *TokenServiceServer) RefreshToken(ctx context.Context, in *permission.RefreshTokenReq) (*permission.RefreshTokenResp, error) {
|
func (s *TokenServiceServer) RefreshToken(ctx context.Context, in *permission.RefreshTokenReq) (*permission.RefreshTokenResp, error) {
|
||||||
l := logic.NewRefreshTokenLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewRefreshTokenLogic(ctx, s.svcCtx)
|
||||||
return l.RefreshToken(in)
|
return l.RefreshToken(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelToken 取消 Token,也包含他裡面的 One Time Toke
|
// CancelToken 取消 Token,也包含他裡面的 One Time Toke
|
||||||
func (s *TokenServiceServer) CancelToken(ctx context.Context, in *permission.CancelTokenReq) (*permission.OKResp, error) {
|
func (s *TokenServiceServer) CancelToken(ctx context.Context, in *permission.CancelTokenReq) (*permission.OKResp, error) {
|
||||||
l := logic.NewCancelTokenLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewCancelTokenLogic(ctx, s.svcCtx)
|
||||||
return l.CancelToken(in)
|
return l.CancelToken(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
||||||
func (s *TokenServiceServer) CancelTokenByUid(ctx context.Context, in *permission.DoTokenByUIDReq) (*permission.OKResp, error) {
|
func (s *TokenServiceServer) CancelTokenByUid(ctx context.Context, in *permission.DoTokenByUIDReq) (*permission.OKResp, error) {
|
||||||
l := logic.NewCancelTokenByUidLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewCancelTokenByUidLogic(ctx, s.svcCtx)
|
||||||
return l.CancelTokenByUid(in)
|
return l.CancelTokenByUid(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelTokenByDeviceID 取消 Token
|
// CancelTokenByDeviceId 取消 Token
|
||||||
func (s *TokenServiceServer) CancelTokenByDeviceId(ctx context.Context, in *permission.DoTokenByDeviceIDReq) (*permission.OKResp, error) {
|
func (s *TokenServiceServer) CancelTokenByDeviceId(ctx context.Context, in *permission.DoTokenByDeviceIDReq) (*permission.OKResp, error) {
|
||||||
l := logic.NewCancelTokenByDeviceIdLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewCancelTokenByDeviceIdLogic(ctx, s.svcCtx)
|
||||||
return l.CancelTokenByDeviceId(in)
|
return l.CancelTokenByDeviceId(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidationToken 驗證這個 Token 有沒有效
|
// ValidationToken 驗證這個 Token 有沒有效
|
||||||
func (s *TokenServiceServer) ValidationToken(ctx context.Context, in *permission.ValidationTokenReq) (*permission.ValidationTokenResp, error) {
|
func (s *TokenServiceServer) ValidationToken(ctx context.Context, in *permission.ValidationTokenReq) (*permission.ValidationTokenResp, error) {
|
||||||
l := logic.NewValidationTokenLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewValidationTokenLogic(ctx, s.svcCtx)
|
||||||
return l.ValidationToken(in)
|
return l.ValidationToken(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens
|
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
|
||||||
func (s *TokenServiceServer) GetUserTokensByDeviceId(ctx context.Context, in *permission.DoTokenByDeviceIDReq) (*permission.Tokens, error) {
|
func (s *TokenServiceServer) GetUserTokensByDeviceId(ctx context.Context, in *permission.DoTokenByDeviceIDReq) (*permission.Tokens, error) {
|
||||||
l := logic.NewGetUserTokensByDeviceIdLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewGetUserTokensByDeviceIdLogic(ctx, s.svcCtx)
|
||||||
return l.GetUserTokensByDeviceId(in)
|
return l.GetUserTokensByDeviceId(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens
|
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
|
||||||
func (s *TokenServiceServer) GetUserTokensByUid(ctx context.Context, in *permission.DoTokenByUIDReq) (*permission.Tokens, error) {
|
func (s *TokenServiceServer) GetUserTokensByUid(ctx context.Context, in *permission.QueryTokenByUIDReq) (*permission.Tokens, error) {
|
||||||
l := logic.NewGetUserTokensByUidLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewGetUserTokensByUidLogic(ctx, s.svcCtx)
|
||||||
return l.GetUserTokensByUid(in)
|
return l.GetUserTokensByUid(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
||||||
func (s *TokenServiceServer) NewOneTimeToken(ctx context.Context, in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
|
func (s *TokenServiceServer) NewOneTimeToken(ctx context.Context, in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
|
||||||
l := logic.NewNewOneTimeTokenLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewNewOneTimeTokenLogic(ctx, s.svcCtx)
|
||||||
return l.NewOneTimeToken(in)
|
return l.NewOneTimeToken(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelOneTimeToken 取消一次性使用
|
// CancelOneTimeToken 取消一次性使用
|
||||||
func (s *TokenServiceServer) CancelOneTimeToken(ctx context.Context, in *permission.CreateOneTimeTokenReq) (*permission.CreateOneTimeTokenResp, error) {
|
func (s *TokenServiceServer) CancelOneTimeToken(ctx context.Context, in *permission.CancelOneTimeTokenReq) (*permission.OKResp, error) {
|
||||||
l := logic.NewCancelOneTimeTokenLogic(ctx, s.svcCtx)
|
l := tokenservicelogic.NewCancelOneTimeTokenLogic(ctx, s.svcCtx)
|
||||||
return l.CancelOneTimeToken(in)
|
return l.CancelOneTimeToken(in)
|
||||||
}
|
}
|
|
@ -1,12 +1,14 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
permissionservice "ark-permission/internal/server/permissionservice"
|
||||||
|
roleservice "ark-permission/internal/server/roleservice"
|
||||||
|
tokenservice "ark-permission/internal/server/tokenservice"
|
||||||
"flag"
|
"flag"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"ark-permission/gen_result/pb/permission"
|
"ark-permission/gen_result/pb/permission"
|
||||||
"ark-permission/internal/config"
|
"ark-permission/internal/config"
|
||||||
"ark-permission/internal/server"
|
|
||||||
"ark-permission/internal/svc"
|
"ark-permission/internal/svc"
|
||||||
|
|
||||||
"github.com/zeromicro/go-zero/core/conf"
|
"github.com/zeromicro/go-zero/core/conf"
|
||||||
|
@ -26,7 +28,9 @@ func main() {
|
||||||
ctx := svc.NewServiceContext(c)
|
ctx := svc.NewServiceContext(c)
|
||||||
|
|
||||||
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
s := zrpc.MustNewServer(c.RpcServerConf, func(grpcServer *grpc.Server) {
|
||||||
permission.RegisterTokenServiceServer(grpcServer, server.NewTokenServiceServer(ctx))
|
permission.RegisterTokenServiceServer(grpcServer, tokenservice.NewTokenServiceServer(ctx))
|
||||||
|
permission.RegisterRoleServiceServer(grpcServer, roleservice.NewRoleServiceServer(ctx))
|
||||||
|
permission.RegisterPermissionServiceServer(grpcServer, permissionservice.NewPermissionServiceServer(ctx))
|
||||||
|
|
||||||
if c.Mode == service.DevMode || c.Mode == service.TestMode {
|
if c.Mode == service.DevMode || c.Mode == service.TestMode {
|
||||||
reflection.Register(grpcServer)
|
reflection.Register(grpcServer)
|
||||||
|
|
|
@ -20,6 +20,7 @@ type (
|
||||||
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
|
DoTokenByDeviceIDReq = permission.DoTokenByDeviceIDReq
|
||||||
DoTokenByUIDReq = permission.DoTokenByUIDReq
|
DoTokenByUIDReq = permission.DoTokenByUIDReq
|
||||||
OKResp = permission.OKResp
|
OKResp = permission.OKResp
|
||||||
|
QueryTokenByUIDReq = permission.QueryTokenByUIDReq
|
||||||
RefreshTokenReq = permission.RefreshTokenReq
|
RefreshTokenReq = permission.RefreshTokenReq
|
||||||
RefreshTokenResp = permission.RefreshTokenResp
|
RefreshTokenResp = permission.RefreshTokenResp
|
||||||
Token = permission.Token
|
Token = permission.Token
|
||||||
|
@ -35,16 +36,16 @@ type (
|
||||||
RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error)
|
RefreshToken(ctx context.Context, in *RefreshTokenReq, opts ...grpc.CallOption) (*RefreshTokenResp, error)
|
||||||
// CancelToken 取消 Token,也包含他裡面的 One Time Toke
|
// CancelToken 取消 Token,也包含他裡面的 One Time Toke
|
||||||
CancelToken(ctx context.Context, in *CancelTokenReq, opts ...grpc.CallOption) (*OKResp, error)
|
CancelToken(ctx context.Context, in *CancelTokenReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||||
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
||||||
CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error)
|
CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||||
// CancelTokenByDeviceID 取消 Token
|
// CancelTokenByDeviceId 取消 Token
|
||||||
CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error)
|
CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error)
|
||||||
// ValidationToken 驗證這個 Token 有沒有效
|
// ValidationToken 驗證這個 Token 有沒有效
|
||||||
ValidationToken(ctx context.Context, in *ValidationTokenReq, opts ...grpc.CallOption) (*ValidationTokenResp, error)
|
ValidationToken(ctx context.Context, in *ValidationTokenReq, opts ...grpc.CallOption) (*ValidationTokenResp, error)
|
||||||
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens
|
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
|
||||||
GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error)
|
GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error)
|
||||||
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens
|
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
|
||||||
GetUserTokensByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error)
|
GetUserTokensByUid(ctx context.Context, in *QueryTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error)
|
||||||
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
// NewOneTimeToken 建立一次性使用,例如:RefreshToken
|
||||||
NewOneTimeToken(ctx context.Context, in *CreateOneTimeTokenReq, opts ...grpc.CallOption) (*CreateOneTimeTokenResp, error)
|
NewOneTimeToken(ctx context.Context, in *CreateOneTimeTokenReq, opts ...grpc.CallOption) (*CreateOneTimeTokenResp, error)
|
||||||
// CancelOneTimeToken 取消一次性使用
|
// CancelOneTimeToken 取消一次性使用
|
||||||
|
@ -80,13 +81,13 @@ func (m *defaultTokenService) CancelToken(ctx context.Context, in *CancelTokenRe
|
||||||
return client.CancelToken(ctx, in, opts...)
|
return client.CancelToken(ctx, in, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelTokenByUID 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
// CancelTokenByUid 取消 Token (取消這個用戶從不同 Device 登入的所有 Token),也包含他裡面的 One Time Toke
|
||||||
func (m *defaultTokenService) CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error) {
|
func (m *defaultTokenService) CancelTokenByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*OKResp, error) {
|
||||||
client := permission.NewTokenServiceClient(m.cli.Conn())
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
return client.CancelTokenByUid(ctx, in, opts...)
|
return client.CancelTokenByUid(ctx, in, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CancelTokenByDeviceID 取消 Token
|
// CancelTokenByDeviceId 取消 Token
|
||||||
func (m *defaultTokenService) CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error) {
|
func (m *defaultTokenService) CancelTokenByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*OKResp, error) {
|
||||||
client := permission.NewTokenServiceClient(m.cli.Conn())
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
return client.CancelTokenByDeviceId(ctx, in, opts...)
|
return client.CancelTokenByDeviceId(ctx, in, opts...)
|
||||||
|
@ -98,14 +99,14 @@ func (m *defaultTokenService) ValidationToken(ctx context.Context, in *Validatio
|
||||||
return client.ValidationToken(ctx, in, opts...)
|
return client.ValidationToken(ctx, in, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserTokensByDeviceIDs 取得目前所對應的 DeviceID 所存在的 Tokens
|
// GetUserTokensByDeviceId 取得目前所對應的 DeviceID 所存在的 Tokens
|
||||||
func (m *defaultTokenService) GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error) {
|
func (m *defaultTokenService) GetUserTokensByDeviceId(ctx context.Context, in *DoTokenByDeviceIDReq, opts ...grpc.CallOption) (*Tokens, error) {
|
||||||
client := permission.NewTokenServiceClient(m.cli.Conn())
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
return client.GetUserTokensByDeviceId(ctx, in, opts...)
|
return client.GetUserTokensByDeviceId(ctx, in, opts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserTokensByUID 取得目前所對應的 UID 所存在的 Tokens
|
// GetUserTokensByUid 取得目前所對應的 UID 所存在的 Tokens
|
||||||
func (m *defaultTokenService) GetUserTokensByUid(ctx context.Context, in *DoTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error) {
|
func (m *defaultTokenService) GetUserTokensByUid(ctx context.Context, in *QueryTokenByUIDReq, opts ...grpc.CallOption) (*Tokens, error) {
|
||||||
client := permission.NewTokenServiceClient(m.cli.Conn())
|
client := permission.NewTokenServiceClient(m.cli.Conn())
|
||||||
return client.GetUserTokensByUid(ctx, in, opts...)
|
return client.GetUserTokensByUid(ctx, in, opts...)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue