Code Bird Cloud 对接反馈回复
针对石榴云工程师提交的《文档差异与修复建议书》和《OIDC 集成完整指南》,我方逐项核对代码后的回复。
一、已采纳并修复的问题
感谢贵方工程师详尽的反馈,以下问题确认属实,我方文档已全部修复:
| # | 问题 | 修复内容 |
|---|---|---|
| 1 | organization_roles 格式描述错误 | 已改为字符串数组 ["org_id:role_name"] 格式 |
| 2 | Go struct / TS interface 类型定义错误 | OrganizationRoles 已改为 []string / string[] |
| 3 | CookieStore 4KB 限制风险 | 已添加醒目警告,推荐 Redis session store |
| 6 | react-go.md 缺少组织级登录说明 | 已补充 organization_code 参数传递和角色解析说明 |
| 8 | End Session URL 手动拼接缺少编码 | 已改用 url.Parse + Query.Encode |
| 9 | SameSite=Lax 注释不充分 | 已补充跨站导航的必要性说明 |
| 10 | phone scope 缺失 | 已在示例 scopes 中补充,并添加提示说明 |
UserInfo 响应示例也已补充 gender、phone_number、phone_number_verified 等实际返回字段。
二、需要贵方确认的问题
问题 A:UserInfo 端点不返回 user_id、nickname、introduction、status
贵方在反馈文档(问题 5)和集成指南中提到 UserInfo 端点返回了以下字段:
go
type UserInfoClaims struct {
UserID uint `json:"user_id"` // 用户数字 ID
Nickname string `json:"nickname"` // 昵称
Introduction string `json:"introduction"` // 自我介绍
Status int `json:"status"` // 用户状态
}我方核对了 /oidc/userinfo 端点的完整实现代码,上述四个字段均不在返回范围内。
我方 UserInfo 端点实际返回的完整字段列表如下:
| 字段 | 类型 | 所需 Scope | 说明 |
|---|---|---|---|
sub | string | 始终返回 | 用户唯一标识(nanoid 字符串,非数字) |
name | string | profile | 用户姓名 |
username | string | profile | 用户名 |
picture | string | profile | 头像 URL |
gender | number | profile | 性别(从用户 Profile 中提取) |
updated_at | number | profile | 更新时间(Unix 时间戳) |
email | string | 邮箱地址 | |
email_verified | boolean | 邮箱是否已验证 | |
phone_number | string | phone | 手机号 |
phone_number_verified | boolean | phone | 手机号是否已验证 |
organization_id | string | 组织级登录时 | 当前组织 ID |
organizations | string[] | urn:codebird:scope:organizations | 用户所属组织 ID 列表 |
organization_roles | string[] | urn:codebird:scope:organization_roles | 格式 "org_id:role_name" |
请贵方确认:
user_id、nickname、introduction、status这些字段是否来自贵方系统自己的接口(如/api/.../admin/auth/me),而非我方/oidc/userinfo?- 如果贵方业务确实需要这些字段通过 OIDC UserInfo 返回,请告知我方,可以评估在
profilescope 中扩展。
问题 B:organization_id 类型为 string,非 uint
贵方集成指南中 IDTokenClaims 定义为:
go
type IDTokenClaims struct {
OrganizationID uint `json:"organization_id"` // ← 类型有误
OrganizationCode string `json:"organization_code"`
}我方返回的 organization_id 是 string 类型(nanoid 格式,如 "KkTNqgPGdaixCJfg-0kkZ"),不是整数。
正确定义:
go
type IDTokenClaims struct {
OrganizationID string `json:"organization_id"`
OrganizationCode string `json:"organization_code"`
}请贵方确认:贵方实际代码中是否已使用 string 类型?如果用 uint 接收,Go 的 encoding/json 会因类型不匹配导致该字段解析为零值。
问题 C:OIDC Discovery 端点状态说明
贵方提到"OIDC 发现在某些配置下可能无法正确响应"。我方已验证 /.well-known/openid-configuration 端点功能正常,返回完整配置:
json
{
"issuer": "...",
"authorization_endpoint": "{issuer}/oidc/authorize",
"token_endpoint": "{issuer}/oidc/token",
"userinfo_endpoint": "{issuer}/oidc/userinfo",
"jwks_uri": "{issuer}/.well-known/jwks.json",
"end_session_endpoint": "{issuer}/oidc/end-session",
"id_token_signing_alg_values_supported": ["ES256"],
"scopes_supported": [
"openid", "profile", "email", "phone", "offline_access",
"urn:codebird:scope:organizations",
"urn:codebird:scope:organization_roles"
]
}贵方遇到的发现失败可能是部署时序问题(我方服务尚未完全启动时请求了该端点)。贵方添加的 fallback 回退逻辑作为防御性编程是合理的,但并非我方端点存在缺陷。
请贵方确认:是否能复现该问题?如果能,请提供具体的错误信息和请求时间点,我方会排查。
三、双方一致的确认项
| 项目 | 结论 |
|---|---|
| 签名算法 | ES256(ECDSA P-256)✅ |
organization_roles 格式 | 字符串数组 "org_id:role_name" ✅ |
| 组织级登录参数 | organization_code 或 organization_id 均可 ✅ |
| Token 全部存后端 Session | 正确做法,前端不持有 Token ✅ |
| SameSite 必须为 Lax | OIDC 跨站回调需要 ✅ |
四、对贵方集成指南的建议
贵方的《OIDC 集成完整指南》整体质量很高,架构图清晰,踩坑记录实用。如需作为参考文档留存,建议修正以下几处:
- 移除
UserInfoClaims中不存在的字段:UserID、Nickname、Introduction、Status— 或标注为"贵方系统自行扩展的字段" IDTokenClaims.OrganizationID类型:从uint改为string- OIDC 发现失败描述:建议改为"建议添加 fallback 作为防御性措施",而非"端点可能不可用"
如有疑问请随时沟通。
