feat: 在 OidcLogin 方法中添加当前用户获取逻辑,优化用户绑定流程 Closes #20

This commit is contained in:
2025-09-23 17:55:25 +08:00
parent 27b7612956
commit f59767d914
2 changed files with 38 additions and 33 deletions

View File

@ -19,7 +19,7 @@ type User struct {
type UserOpenID struct { type UserOpenID struct {
gorm.Model gorm.Model
UserID uint `gorm:"uniqueIndex"` UserID uint `gorm:"index"`
User User `gorm:"foreignKey:UserID;references:ID"` User User `gorm:"foreignKey:UserID;references:ID"`
Issuer string `gorm:"index"` // OIDC Issuer Issuer string `gorm:"index"` // OIDC Issuer
Sub string `gorm:"index"` // OIDC Sub openid Sub string `gorm:"index"` // OIDC Sub openid

View File

@ -180,6 +180,7 @@ func (s *UserService) ListOidcConfigs() ([]dto.UserOidcConfigDto, error) {
func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dto.OidcLoginResp, error) { func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dto.OidcLoginResp, error) {
// 验证state // 验证state
currentUser, userOk := ctxutils.GetCurrentUser(ctx)
kvStore := utils.KV.GetInstance() kvStore := utils.KV.GetInstance()
storedName, ok := kvStore.Get(constant.KVKeyOidcState + req.State) storedName, ok := kvStore.Get(constant.KVKeyOidcState + req.State)
if !ok || storedName != req.Name { if !ok || storedName != req.Name {
@ -211,7 +212,7 @@ func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dt
return nil, errs.ErrInternalServer return nil, errs.ErrInternalServer
} }
// 绑定过登录 // 1.绑定过登录
userOpenID, err := repo.User.GetUserOpenIDByIssuerAndSub(oidcConfig.Issuer, userInfo.Sub) userOpenID, err := repo.User.GetUserOpenIDByIssuerAndSub(oidcConfig.Issuer, userInfo.Sub)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errs.ErrInternalServer return nil, errs.ErrInternalServer
@ -233,12 +234,16 @@ func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dt
} }
return resp, nil return resp, nil
} else { } else {
// 若没有绑定过登录,则先通过邮箱查找用户,若没有再创建新用户 // 2.若没有绑定过登录,则判断当前有无用户登录,有则绑定,没有登录先通过邮箱查找用户
user, err := repo.User.GetUserByEmail(userInfo.Email) user := currentUser
if user == nil || !userOk {
user, err = repo.User.GetUserByEmail(userInfo.Email)
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
logrus.Errorln("Failed to get user by email:", err) logrus.Errorln("Failed to get user by email:", err)
return nil, errs.ErrInternalServer return nil, errs.ErrInternalServer
} }
}
if user != nil { if user != nil {
userOpenID = &model.UserOpenID{ userOpenID = &model.UserOpenID{
UserID: user.ID, UserID: user.ID,
@ -262,7 +267,7 @@ func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dt
} }
return resp, nil return resp, nil
} else { } else {
// 第一次登录,创建新用户时才获取头像 // 3.第一次登录,创建新用户时才获取头像
user = &model.User{ user = &model.User{
Username: userInfo.PreferredUsername, Username: userInfo.PreferredUsername,
Nickname: userInfo.Name, Nickname: userInfo.Name,