add login and register api
This commit is contained in:
parent
40812db5bf
commit
bbb6b4b746
|
@ -59,6 +59,7 @@ type (
|
|||
// --- 4. 權杖刷新 ---
|
||||
// RefreshTokenReq 更新 AccessToken
|
||||
RefreshTokenReq {
|
||||
AccessToken string `json:"access_token" validate:"required"`
|
||||
RefreshToken string `json:"refresh_token" validate:"required"`
|
||||
}
|
||||
|
||||
|
|
|
@ -2,3 +2,4 @@ package domain
|
|||
|
||||
const SuccessCode = 10200
|
||||
const SuccessMessage = "success"
|
||||
const DefaultScope = "gateway"
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"backend/internal/svc"
|
||||
"backend/internal/types"
|
||||
"backend/pkg/permission/domain/entity"
|
||||
"backend/pkg/permission/domain/token"
|
||||
"context"
|
||||
"time"
|
||||
)
|
||||
|
||||
// 生成 Token
|
||||
func generateToken(svc *svc.ServiceContext, ctx context.Context, req *types.LoginReq, uid string) (entity.TokenResp, error) {
|
||||
// scope role 要修改,refresh tl
|
||||
role := "user"
|
||||
|
||||
tk, err := svc.TokenUC.NewToken(ctx, entity.AuthorizationReq{
|
||||
GrantType: token.ClientCredentials.ToString(),
|
||||
DeviceID: uid, // TODO 沒傳暫時先用UID 替代
|
||||
Scope: "gateway",
|
||||
IsRefreshToken: true,
|
||||
Expires: time.Now().UTC().Add(svc.Config.Token.AccessTokenExpiry).Unix(),
|
||||
Data: map[string]string{
|
||||
"uid": uid,
|
||||
},
|
||||
Role: role,
|
||||
Account: req.LoginID,
|
||||
})
|
||||
if err != nil {
|
||||
return entity.TokenResp{}, err
|
||||
}
|
||||
|
||||
return entity.TokenResp{
|
||||
AccessToken: tk.AccessToken,
|
||||
TokenType: tk.TokenType,
|
||||
ExpiresIn: tk.ExpiresIn,
|
||||
RefreshToken: tk.RefreshToken,
|
||||
}, nil
|
||||
|
||||
}
|
|
@ -1,6 +1,10 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"backend/pkg/library/errs"
|
||||
"backend/pkg/library/errs/code"
|
||||
memberD "backend/pkg/member/domain/member"
|
||||
member "backend/pkg/member/domain/usecase"
|
||||
"context"
|
||||
|
||||
"backend/internal/svc"
|
||||
|
@ -15,7 +19,7 @@ type LoginLogic struct {
|
|||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 使用者登入
|
||||
// NewLoginLogic 使用者登入
|
||||
func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic {
|
||||
return &LoginLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
|
@ -25,7 +29,65 @@ func NewLoginLogic(ctx context.Context, svcCtx *svc.ServiceContext) *LoginLogic
|
|||
}
|
||||
|
||||
func (l *LoginLogic) Login(req *types.LoginReq) (resp *types.LoginResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
//var result member.VerifyAuthResultResponse
|
||||
switch req.AuthMethod {
|
||||
case "credentials":
|
||||
cr, err := l.svcCtx.AccountUC.VerifyPlatformAuthResult(l.ctx, member.VerifyAuthResultRequest{
|
||||
Account: req.LoginID,
|
||||
Token: req.Credentials.Password,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
if !cr.Status {
|
||||
return nil, errs.Unauthorized("failed to verify password")
|
||||
}
|
||||
case "platform":
|
||||
switch req.Platform.Provider {
|
||||
case memberD.Google.ToString():
|
||||
_, err := l.svcCtx.AccountUC.VerifyGoogleAuthResult(l.ctx, member.VerifyAuthResultRequest{
|
||||
Account: req.LoginID,
|
||||
Token: req.Platform.Token,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case memberD.Line.ToString():
|
||||
// 原始平台驗證
|
||||
accessToken, err := l.svcCtx.AccountUC.LineCodeToAccessToken(l.ctx, req.LoginID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// 換資料
|
||||
userInfo, err := l.svcCtx.AccountUC.LineGetProfileByAccessToken(l.ctx, accessToken.AccessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
req.LoginID = userInfo.UserID
|
||||
default:
|
||||
return nil, errs.InvalidFormatWithScope(code.CloudEPMember, "unsupported 3 party platform")
|
||||
}
|
||||
default:
|
||||
return nil, errs.InvalidFormatWithScope(code.CloudEPMember, "failed to get correct auth method")
|
||||
}
|
||||
|
||||
account, err := l.svcCtx.AccountUC.GetUIDByAccount(l.ctx, member.GetUIDByAccountRequest{
|
||||
Account: req.LoginID,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
tk, err := generateToken(l.svcCtx, l.ctx, req, account.UID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.LoginResp{
|
||||
UID: account.UID,
|
||||
AccessToken: tk.AccessToken,
|
||||
RefreshToken: tk.RefreshToken,
|
||||
TokenType: tk.TokenType,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -1,7 +1,10 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"backend/internal/domain"
|
||||
"backend/pkg/permission/domain/entity"
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"backend/internal/svc"
|
||||
"backend/internal/types"
|
||||
|
@ -15,7 +18,7 @@ type RefreshTokenLogic struct {
|
|||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 刷新 Access Token
|
||||
// NewRefreshTokenLogic 刷新 Access Token
|
||||
func NewRefreshTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RefreshTokenLogic {
|
||||
return &RefreshTokenLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
|
@ -25,7 +28,24 @@ func NewRefreshTokenLogic(ctx context.Context, svcCtx *svc.ServiceContext) *Refr
|
|||
}
|
||||
|
||||
func (l *RefreshTokenLogic) RefreshToken(req *types.RefreshTokenReq) (resp *types.RefreshTokenResp, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
data, err := l.svcCtx.TokenUC.ReadTokenBasicData(l.ctx, req.AccessToken)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return
|
||||
tk, err := l.svcCtx.TokenUC.RefreshToken(l.ctx, entity.RefreshTokenReq{
|
||||
Token: req.RefreshToken,
|
||||
Scope: domain.DefaultScope,
|
||||
Expires: time.Now().UTC().Add(l.svcCtx.Config.Token.RefreshTokenExpiry).Unix(),
|
||||
DeviceID: data["uid"],
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &types.RefreshTokenResp{
|
||||
AccessToken: tk.Token,
|
||||
RefreshToken: tk.OneTimeToken,
|
||||
TokenType: tk.TokenType,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -7,11 +7,7 @@ import (
|
|||
"backend/pkg/library/errs/code"
|
||||
mb "backend/pkg/member/domain/member"
|
||||
member "backend/pkg/member/domain/usecase"
|
||||
"backend/pkg/permission/domain/entity"
|
||||
"backend/pkg/permission/domain/token"
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"google.golang.org/protobuf/proto"
|
||||
|
||||
"github.com/zeromicro/go-zero/core/logx"
|
||||
|
@ -82,7 +78,7 @@ func (l *RegisterLogic) Register(req *types.LoginReq) (resp *types.LoginResp, er
|
|||
|
||||
// Step 5: 生成 Token
|
||||
req.LoginID = bd.CreateAccountReq.LoginID
|
||||
tk, err := l.generateToken(req, account.UID)
|
||||
tk, err := generateToken(l.svcCtx, l.ctx, req, account.UID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -184,34 +180,3 @@ func buildLineData(ctx context.Context, req *types.LoginReq, svc *svc.ServiceCon
|
|||
},
|
||||
}, nil
|
||||
}
|
||||
|
||||
// 生成 Token
|
||||
func (l *RegisterLogic) generateToken(req *types.LoginReq, uid string) (entity.TokenResp, error) {
|
||||
// scope role 要修改,refresh tl
|
||||
role := "user"
|
||||
|
||||
tk, err := l.svcCtx.TokenUC.NewToken(l.ctx, entity.AuthorizationReq{
|
||||
GrantType: token.ClientCredentials.ToString(),
|
||||
DeviceID: uid, // TODO 沒傳暫時先用UID 替代
|
||||
Scope: "gateway",
|
||||
IsRefreshToken: true,
|
||||
Expires: time.Now().UTC().Add(l.svcCtx.Config.Token.AccessTokenExpiry).Unix(),
|
||||
Data: map[string]string{
|
||||
"uid": uid,
|
||||
"role": role,
|
||||
},
|
||||
Role: role,
|
||||
Account: req.LoginID,
|
||||
})
|
||||
if err != nil {
|
||||
return entity.TokenResp{}, err
|
||||
}
|
||||
|
||||
return entity.TokenResp{
|
||||
AccessToken: tk.AccessToken,
|
||||
TokenType: tk.TokenType,
|
||||
ExpiresIn: tk.ExpiresIn,
|
||||
RefreshToken: tk.RefreshToken,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
|
|
@ -15,7 +15,6 @@ type RequestPasswordResetLogic struct {
|
|||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 請求發送密碼重設驗證碼
|
||||
func NewRequestPasswordResetLogic(ctx context.Context, svcCtx *svc.ServiceContext) *RequestPasswordResetLogic {
|
||||
return &RequestPasswordResetLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
|
@ -24,6 +23,7 @@ func NewRequestPasswordResetLogic(ctx context.Context, svcCtx *svc.ServiceContex
|
|||
}
|
||||
}
|
||||
|
||||
// RequestPasswordReset 請求發送密碼重設驗證碼 aka 忘記密碼
|
||||
func (l *RequestPasswordResetLogic) RequestPasswordReset(req *types.RequestPasswordResetReq) (resp *types.RespOK, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ type VerifyPasswordResetCodeLogic struct {
|
|||
svcCtx *svc.ServiceContext
|
||||
}
|
||||
|
||||
// 校驗密碼重設驗證碼
|
||||
func NewVerifyPasswordResetCodeLogic(ctx context.Context, svcCtx *svc.ServiceContext) *VerifyPasswordResetCodeLogic {
|
||||
return &VerifyPasswordResetCodeLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
|
@ -24,6 +23,7 @@ func NewVerifyPasswordResetCodeLogic(ctx context.Context, svcCtx *svc.ServiceCon
|
|||
}
|
||||
}
|
||||
|
||||
// VerifyPasswordResetCode 校驗密碼重設驗證碼(頁面需求,預先檢查看看, 顯示表演用)
|
||||
func (l *VerifyPasswordResetCodeLogic) VerifyPasswordResetCode(req *types.VerifyCodeReq) (resp *types.RespOK, err error) {
|
||||
// todo: add your logic here and delete this line
|
||||
|
||||
|
|
|
@ -49,6 +49,7 @@ type PlatformPayload struct {
|
|||
}
|
||||
|
||||
type RefreshTokenReq struct {
|
||||
AccessToken string `json:"access_token" validate:"required"`
|
||||
RefreshToken string `json:"refresh_token" validate:"required"`
|
||||
}
|
||||
|
||||
|
|
|
@ -174,12 +174,13 @@ func (use *TokenUseCase) RefreshToken(ctx context.Context, req entity.RefreshTok
|
|||
credentials := token.ClientCredentials
|
||||
newToken, err := use.newToken(ctx, &entity.AuthorizationReq{
|
||||
GrantType: credentials.ToString(),
|
||||
Scope: req.Scope,
|
||||
Scope: claimsData.Scope(),
|
||||
DeviceID: req.DeviceID,
|
||||
Data: claimsData,
|
||||
Expires: req.Expires,
|
||||
IsRefreshToken: true,
|
||||
Account: req.DeviceID,
|
||||
Account: claimsData.Account(),
|
||||
Role: claimsData.Role(),
|
||||
})
|
||||
if err != nil {
|
||||
return entity.RefreshTokenResp{},
|
||||
|
@ -474,9 +475,9 @@ func (use *TokenUseCase) wrapTokenError(ctx context.Context, param wrapTokenErro
|
|||
{Key: "func", Value: param.funcName},
|
||||
{Key: "err", Value: param.err.Error()},
|
||||
}
|
||||
|
||||
|
||||
logx.WithContext(ctx).Errorw(param.message, logFields...)
|
||||
|
||||
|
||||
wrappedErr := errs.NewError(
|
||||
code.CatToken,
|
||||
code.CatToken,
|
||||
|
@ -595,7 +596,7 @@ func (use *TokenUseCase) BlacklistToken(ctx context.Context, token string, reaso
|
|||
})
|
||||
}
|
||||
|
||||
logx.WithContext(ctx).Infow("token blacklisted",
|
||||
logx.WithContext(ctx).Infow("token blacklisted",
|
||||
logx.Field("jti", jtiStr),
|
||||
logx.Field("uid", uid),
|
||||
logx.Field("reason", reason))
|
||||
|
|
|
@ -57,3 +57,21 @@ func (tc tokenClaims) UID() string {
|
|||
|
||||
return uid
|
||||
}
|
||||
|
||||
func (tc tokenClaims) Scope() string {
|
||||
scope, ok := tc["scope"]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
return scope
|
||||
}
|
||||
|
||||
func (tc tokenClaims) Account() string {
|
||||
scope, ok := tc["account"]
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
return scope
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue