认证流程迁移到 oauth 风格,登出接口改为 /revoke,重构接口代码到 service
This commit is contained in:
@@ -3,42 +3,25 @@ package services
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"platform/web/models"
|
||||
m "platform/web/models"
|
||||
q "platform/web/queries"
|
||||
"time"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
var Auth = &authService{}
|
||||
|
||||
type AuthServiceError string
|
||||
|
||||
func (e AuthServiceError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
type AuthServiceOauthError string
|
||||
|
||||
func (e AuthServiceOauthError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
var (
|
||||
ErrOauthInvalidRequest = AuthServiceOauthError("invalid_request")
|
||||
ErrOauthInvalidClient = AuthServiceOauthError("invalid_client")
|
||||
ErrOauthInvalidGrant = AuthServiceOauthError("invalid_grant")
|
||||
ErrOauthInvalidScope = AuthServiceOauthError("invalid_scope")
|
||||
ErrOauthUnauthorizedClient = AuthServiceOauthError("unauthorized_client")
|
||||
ErrOauthUnsupportedGrantType = AuthServiceOauthError("unsupported_grant_type")
|
||||
)
|
||||
|
||||
type authService struct{}
|
||||
|
||||
// OauthAuthorizationCode 验证授权码
|
||||
func (s *authService) OauthAuthorizationCode(ctx context.Context, client *models.Client, code, redirectURI, codeVerifier string) (*TokenDetails, error) {
|
||||
func (s *authService) OauthAuthorizationCode(ctx context.Context, client *m.Client, code, redirectURI, codeVerifier string) (*TokenDetails, error) {
|
||||
// TODO: 从数据库验证授权码
|
||||
return nil, errors.New("TODO")
|
||||
}
|
||||
|
||||
// OauthClientCredentials 验证客户端凭证
|
||||
func (s *authService) OauthClientCredentials(ctx context.Context, client *models.Client, scope ...string) (*TokenDetails, error) {
|
||||
func (s *authService) OauthClientCredentials(ctx context.Context, client *m.Client, scope ...string) (*TokenDetails, error) {
|
||||
|
||||
var clientType PayloadType
|
||||
switch client.Spec {
|
||||
@@ -75,7 +58,7 @@ func (s *authService) OauthClientCredentials(ctx context.Context, client *models
|
||||
}
|
||||
|
||||
// OauthRefreshToken 验证刷新令牌
|
||||
func (s *authService) OauthRefreshToken(ctx context.Context, client *models.Client, refreshToken string, scope ...[]string) (*TokenDetails, error) {
|
||||
func (s *authService) OauthRefreshToken(ctx context.Context, _ *m.Client, refreshToken string, scope ...[]string) (*TokenDetails, error) {
|
||||
// TODO: 从数据库验证刷新令牌
|
||||
details, err := Session.Refresh(ctx, refreshToken)
|
||||
if err != nil {
|
||||
@@ -85,6 +68,114 @@ func (s *authService) OauthRefreshToken(ctx context.Context, client *models.Clie
|
||||
return details, nil
|
||||
}
|
||||
|
||||
// OauthPassword 验证密码
|
||||
func (s *authService) OauthPassword(ctx context.Context, _ *m.Client, data *GrantPasswordData, ip, agent string) (*TokenDetails, error) {
|
||||
var user *m.User
|
||||
err := q.Q.Transaction(func(tx *q.Query) error {
|
||||
|
||||
switch data.LoginType {
|
||||
case OauthGrantPasswordTypePhoneCode:
|
||||
// 验证验证码
|
||||
err := Verifier.VerifySms(ctx, data.Username, data.Password)
|
||||
if err != nil {
|
||||
if errors.Is(err, ErrVerifierServiceInvalid) {
|
||||
return ErrOauthInvalidRequest
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
// 查找用户
|
||||
user, err =
|
||||
tx.User.Where(tx.User.Phone.Eq(data.Username)).Take()
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
case OauthGrantPasswordTypeEmailCode:
|
||||
var err error
|
||||
user, err = tx.User.Where(tx.User.Email.Eq(data.Username)).Take()
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
case OauthGrantPasswordTypePassword:
|
||||
var err error
|
||||
user, err = tx.User.
|
||||
Where(tx.User.Or(
|
||||
tx.User.Phone.Eq(data.Username),
|
||||
tx.User.Email.Eq(data.Username),
|
||||
tx.User.Username.Eq(data.Username),
|
||||
)).
|
||||
Take()
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return err
|
||||
}
|
||||
default:
|
||||
return ErrOauthInvalidRequest
|
||||
}
|
||||
|
||||
// 如果用户不存在,初始化用户 todo 初始化默认权限信息
|
||||
if user == nil {
|
||||
user = &m.User{
|
||||
Phone: data.Username,
|
||||
Username: data.Username,
|
||||
}
|
||||
}
|
||||
|
||||
// 更新用户的登录时间
|
||||
user.LastLogin = time.Now()
|
||||
user.LastLoginHost = ip
|
||||
user.LastLoginAgent = agent
|
||||
if err := tx.User.Omit(q.User.AdminID).Save(user); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// 保存到会话
|
||||
auth := AuthContext{
|
||||
Payload: Payload{
|
||||
Id: user.ID,
|
||||
Type: PayloadUser,
|
||||
Name: user.Name,
|
||||
Avatar: user.Avatar,
|
||||
},
|
||||
}
|
||||
|
||||
duration := DefaultSessionConfig
|
||||
if !data.Remember {
|
||||
duration.RefreshTokenDuration = 0
|
||||
}
|
||||
token, err := Session.Create(ctx, auth)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
type GrantCodeData struct {
|
||||
Code string `json:"code" form:"code"`
|
||||
RedirectURI string `json:"redirect_uri" form:"redirect_uri"`
|
||||
CodeVerifier string `json:"code_verifier" form:"code_verifier"`
|
||||
}
|
||||
|
||||
type GrantClientData struct {
|
||||
}
|
||||
|
||||
type GrantRefreshData struct {
|
||||
RefreshToken string `json:"refresh_token" form:"refresh_token"`
|
||||
}
|
||||
|
||||
type GrantPasswordData struct {
|
||||
LoginType OauthGrantLoginType `json:"login_type" form:"login_type"`
|
||||
Username string `json:"username" form:"username"`
|
||||
Password string `json:"password" form:"password"`
|
||||
Remember bool `json:"remember" form:"remember"`
|
||||
}
|
||||
|
||||
type OauthGrantType string
|
||||
|
||||
const (
|
||||
@@ -101,3 +192,18 @@ const (
|
||||
OauthGrantPasswordTypePhoneCode = OauthGrantLoginType("phone_code")
|
||||
OauthGrantPasswordTypeEmailCode = OauthGrantLoginType("email_code")
|
||||
)
|
||||
|
||||
type AuthServiceError string
|
||||
|
||||
func (e AuthServiceError) Error() string {
|
||||
return string(e)
|
||||
}
|
||||
|
||||
var (
|
||||
ErrOauthInvalidRequest = AuthServiceError("invalid_request")
|
||||
ErrOauthInvalidClient = AuthServiceError("invalid_client")
|
||||
ErrOauthInvalidGrant = AuthServiceError("invalid_grant")
|
||||
ErrOauthInvalidScope = AuthServiceError("invalid_scope")
|
||||
ErrOauthUnauthorizedClient = AuthServiceError("unauthorized_client")
|
||||
ErrOauthUnsupportedGrantType = AuthServiceError("unsupported_grant_type")
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user