plan.md 4.6 KB

017 实施计划

架构:最大化复用现有登录链路

provider 凭证 ──▶ OAuthVerifyService.verify(provider, credential) ──▶ providerUid
                                                                        │
                ┌───────────────────────────────────────────────────────┘
                ▼
        查 info_user_oauth (provider, provider_uid)
        ├─ 命中 → 取 InfoUser → 校 status/del_flag → issueToken(provider) → 返回
        └─ 未命中 → Redis 缓存 {provider,providerUid}(tempKey,TTL5m) → 返回 needPhone+tempKey
                                                                        │
                ┌───────────────────────────────────────────────────────┘
                ▼  (前端引导输手机号 → getcode 发短信)
        oauthBindPhone(tempKey, phone, code)
          取 providerUid + 验短信(复用 lodeing: redis code==input || "8888")
          getuser(phone):
            ├─ 已注册 → 关联(写 oauth)
            └─ 未注册 → createUser(phone) 新建 → 写 oauth
          → issueToken(provider) → 返回
  • token 签发:复用 JwtUtil.setToken(CacheConstants.USER_TOKEN_KEY, loginDto),仅给 LoginUserDtoprovider 字段并在 setToken 写入 claim。
  • 新建用户:复用 createUser 的「建 InfoUser + 建钱包 + 删旧 token」逻辑;昵称=手机号不变。
  • 短信:复用 getcode 发送 + lodeing 的校验(key=phone 去+,万能码 8888)。

数据模型

CREATE TABLE info_user_oauth (
  id           BIGINT AUTO_INCREMENT PRIMARY KEY,
  user_id      BIGINT       NOT NULL COMMENT '关联 info_user.user_id',
  provider     VARCHAR(16)  NOT NULL COMMENT 'apple/google/line',
  provider_uid VARCHAR(64)  NOT NULL COMMENT '三方稳定用户ID(Apple sub / Google sub / LINE userId)',
  create_time  DATETIME     DEFAULT CURRENT_TIMESTAMP,
  UNIQUE KEY uk_provider_uid (provider, provider_uid),
  KEY idx_user_id (user_id)
) COMMENT='三方账号绑定';

API 契约

1) POST /infouser/user/oauthLogin (@Anonymous)

请求 OAuthLoginDto

provider     apple|google|line
credential   identityToken(Apple) / idToken(Google) / accessToken(LINE)
cid, cidType, deviceToken, voIPToken   // 推送字段,与现有登录一致

响应(命中):

{ code:200, msg, data: InfoUser, token }   // token claim provider=本次渠道

响应(未命中,首次):

{ code:200, msg, data:{ status:"needPhone", tempKey } }

2) POST /infouser/user/oauthBindPhone (@Anonymous)

请求 OAuthBindDto

tempKey, phone, code   // code=短信验证码
cid, cidType, deviceToken, voIPToken

响应:{ code:200, msg, data: InfoUser, token }

三家凭证校验(OAuthVerifyService)

provider 凭证 校验 取 providerUid 依赖
apple identityToken(ES256 JWT) appleid.apple.com/auth/keys(JWKS) 验签 + 校 iss/aud/exp sub nimbus-jose-jwt(新增)
google ID-Token GET oauth2.googleapis.com/tokeninfo?id_token= 取 claims + 校 aud=clientId sub httpclient4(已有)
line access_token GET api.line.me/v2/profile(Bearer) userId httpclient4(已有)

Google 走 tokeninfo HTTP 而非 firebase-admin,因后者需初始化 FirebaseApp+服务账号(项目未配置),tokeninfo 零配置即可。

文件清单

类型 文件
新增实体 ruoyi-system/.../domain/InfoUserOauth.java
新增 mapper ruoyi-system/.../mapper/InfoUserOauthMapper.java(BaseMapper,无 XML)
新增校验服务 ruoyi-admin/.../utils/oauth/OAuthVerifyService.java
新增 DTO ruoyi-admin/.../user/dto/OAuthLoginDto.javaOAuthBindDto.java
改 controller ruoyi-admin/.../user/InfoUserController.java(+2 方法)
改 token ruoyi-common/.../model/LoginUserDto.javaruoyi-system/.../utils/JwtUtil.java
改配置 ruoyi-admin/src/main/resources/application.yml(oauth 段)
改依赖 ruoyi-admin/pom.xml(+nimbus-jose-jwt)
SQL updatesql/sql.md

风险 / 待验证

  • Apple / Google / LINE 的凭证校验需用各家真实 token + 正确 clientId/bundleId 联调才能端到端验证;配置值(clientId/jwks url)由前端/运营提供后填入 application.yml。
  • Apple JWKS 建议加缓存(key 偶尔轮换);初版每次拉取或加内存缓存。