顺序执行;每步完成后编译验证。
updatesql/sql.md 加 info_user_oauth 建表(含 uk_provider_uid 唯一索引、idx_user_id)。InfoUserOauth.java(@TableName=info_user_oauth,字段 id/userId/provider/providerUid/createTime)。InfoUserOauthMapper extends BaseMapper<InfoUserOauth>(无 XML)。provider 字段。provider claim(非空才写)。oauth.apple.clientId/jwks-url、oauth.google.clientId/tokeninfo-url、oauth.line.profile-url。nimbus-jose-jwt。verify(provider, credential) → providerUid;Apple(nimbus 验 ES256)、Google(tokeninfo)、LINE(v2/profile),校 audience/iss/exp。评审发现并修复(均已 JDK21 编译通过):
OAuthVerifyService.httpGet 原用 HttpClients.createDefault() 无超时,provider 慢/不可达会拖垮请求线程池 → 加 RequestConfig(连接 5s / 读取 10s / 获取连接 5s)。oauthBindPhone 用 getuser(phone) 只滤 del_flag、不滤 status,停用账号(status≠0)能通过三方绑定绕过停用 → 加 status!=0 拦截(与 lodeing / oauthLogin 已绑定路径一致),文案复用 no.user.stop。aud.get(0) 在多 audience 时可能漏判 → 改 aud.contains(appleClientId)。no.oauth.* 共 10 个 key,写入 5 份 properties(messages / zh_CN / zh_TW / en_US / vi);OAuthVerifyService 异常文案与 InfoUserController 提示全部走 MessageUtils.message,与 lodeing 风格一致。新增 key:
no.oauth.provider.blank / needphone / tempkey.missing / tempkey.expiredno.oauth.credential.blank / provider.unsupported / token.invalid / token.expired / audience.mismatch / verify.fail(带 {0} 渠道名、verify.fail 带 {1} 异常详情)