本文说明如何把 Gitee 第三方应用 Gitee.VisualStudio 接入 SonnetDB Connect。目标是让 Visual Studio 客户端只接触 client_id、授权码和 SonnetDB Connect 入口;client_secret 保存在 sonnetdb.com 后台数据库,由服务端完成 Gitee token 交换。
架构
Visual Studio 客户端
-> https://connect.sonnetdb.com/connect/oauth
-> Gitee OAuth 授权页
-> Visual Studio 本地/自定义回调地址,拿到 code
-> POST https://connect.sonnetdb.com/oauth/token
-> SonnetDB Connect 服务端携带数据库里的 Gitee client_secret 调 Gitee token endpoint
-> Visual Studio 客户端拿到 Gitee access_token 响应
Gitee 第三方应用
在 Gitee 第三方应用后台创建或编辑 Gitee.VisualStudio:
| 字段 | 值 |
|---|---|
| 应用名称 | Gitee.VisualStudio |
| Client ID | 使用 Gitee 分配的值 |
| Client Secret | 只录入 SonnetDB 后台,不写入客户端、仓库、日志或 .env |
| 回调地址 | Visual Studio 客户端实际使用的 redirect URI |
回调地址必须和 SonnetDB 后台客户端配置中的 Allowed Redirect URI 完全一致,也必须和发起授权时传入的 redirect_uri 完全一致。
SonnetDB 后台配置
进入 https://sonnetdb.com/admin/connect-oauth,新增 OAuth 服务方:
| 字段 | 值 |
|---|---|
| Service Domain | gitee.com |
| 显示名称 | Gitee |
| Authorization Endpoint | https://gitee.com/oauth/authorize |
| Token Endpoint | https://gitee.com/oauth/token |
| Client ID | Gitee 分配的 Client ID |
| Client Secret | Gitee 分配的 Client Secret |
| 客户端名称 | Gitee.VisualStudio |
| 客户端类型 | native |
| 允许回调地址 | Visual Studio 客户端实际 redirect URI |
| 默认 Scope | user_info |
保存后后台会自动创建同名默认客户端。列表中应能看到:
- 服务方
gitee.com - 客户端
Gitee.VisualStudio - Secret 状态为已配置
- 允许回调地址为 Visual Studio 客户端实际回调地址
Visual Studio 客户端授权
客户端打开系统浏览器访问:
https://connect.sonnetdb.com/connect/oauth?service_domain=gitee.com&client_id=<gitee_client_id>&redirect_uri=<url_encoded_redirect_uri>&response_type=code&scope=user_info&state=<opaque_state>
也可以使用直跳入口:
https://connect.sonnetdb.com/oauth/authorize?service_domain=gitee.com&client_id=<gitee_client_id>&redirect_uri=<url_encoded_redirect_uri>&response_type=code&scope=user_info&state=<opaque_state>
参数要求:
service_domain固定为gitee.com。client_id使用 Gitee 的 Client ID。redirect_uri使用 Visual Studio 客户端注册的回调地址,并 URL encode。response_type固定为code。scope第一版使用user_info。state必须由客户端生成随机值,回调时校验一致。
授权完成后,Gitee 会回调 Visual Studio 客户端配置的 redirect_uri,并附带 code 和 state。
Token 交换
Visual Studio 客户端收到 code 后,调用 SonnetDB Connect:
POST https://connect.sonnetdb.com/oauth/token
Content-Type: application/json
{
"service_domain": "gitee.com",
"grant_type": "authorization_code",
"code": "<code_from_gitee>",
"redirect_uri": "<same_redirect_uri_used_in_authorize>",
"client_id": "<gitee_client_id>",
"state": "<same_state>"
}
SonnetDB Connect 会从数据库读取 client_secret,向 Gitee https://gitee.com/oauth/token 交换 token,并把上游 JSON 响应返回给客户端。
客户端也可以使用 application/x-www-form-urlencoded,字段名保持一致。
刷新 Token
如果 Gitee 返回 refresh_token,客户端可以通过 SonnetDB Connect 刷新:
POST https://connect.sonnetdb.com/oauth/token
Content-Type: application/json
{
"service_domain": "gitee.com",
"grant_type": "refresh_token",
"refresh_token": "<refresh_token_from_gitee>",
"client_id": "<gitee_client_id>"
}
客户端安全要求
- 不在 Visual Studio 扩展源码、配置文件、日志或遥测中保存
client_secret。 - 不把 OAuth
code、access_token、refresh_token写入普通日志。 state使用高强度随机值,并在回调时校验。redirect_uri必须固定或受控,不允许用户任意输入后直接用于授权。- Token 保存到操作系统安全凭据存储,不保存到明文文件。
联调检查
- 后台
/admin/connect-oauth能看到gitee.com和Gitee.VisualStudio。 - Secret 状态显示已配置,后台不回显明文。
- 浏览器打开授权 URL 后,会先看到 SonnetDB Connect 确认页,再跳到 Gitee 授权页。
- Gitee 回调 Visual Studio 客户端,客户端收到
code和原始state。 - 客户端调用 SonnetDB Connect
/oauth/token成功返回 Gitee token JSON。 - 后台最近授权审计出现
authorize_redirect和token_exchange记录。
给 AI 编码智能体的实现提示词
你要在 Visual Studio 客户端/扩展中实现 Gitee.VisualStudio OAuth 登录,对接 SonnetDB Connect,不要直接对接 Gitee token endpoint。
约束:
- 不要把 Gitee Client Secret 写入客户端源码、配置、日志、测试快照或仓库。
- Client Secret 只在 sonnetdb.com 后台 /admin/connect-oauth 配置,并存入平台数据库。
- 客户端只持有 Gitee Client ID、redirect URI、state、authorization code 和 token 响应。
- 使用系统浏览器打开授权 URL,不在嵌入式 WebView 中输入 Gitee 账号密码。
- 使用随机 state 防 CSRF,回调后必须校验 state。
- redirect_uri 必须和 Gitee 第三方应用以及 SonnetDB 后台 Allowed Redirect URI 完全一致。
授权流程:
1. 生成随机 state。
2. 构造授权 URL:
https://connect.sonnetdb.com/connect/oauth?service_domain=gitee.com&client_id=<client_id>&redirect_uri=<url_encoded_redirect_uri>&response_type=code&scope=user_info&state=<state>
3. 用系统浏览器打开授权 URL。
4. 在本地回调监听或 VS 扩展自定义回调中接收 Gitee 返回的 code/state。
5. 校验 state;不一致则中止。
6. 调用 SonnetDB Connect token endpoint:
POST https://connect.sonnetdb.com/oauth/token
Content-Type: application/json
body:
{
"service_domain": "gitee.com",
"grant_type": "authorization_code",
"code": "<code>",
"redirect_uri": "<same_redirect_uri>",
"client_id": "<client_id>"
}
7. 解析返回的 Gitee token JSON。不要记录 access_token/refresh_token。
8. 将 token 存入操作系统安全凭据存储。
9. 如果 token 交换失败,展示友好错误,并提示用户重试或检查后台 /admin/connect-oauth 配置。
验收:
- 客户端仓库中搜索不到 Client Secret。
- 授权 URL 使用 connect.sonnetdb.com,不直接使用 gitee.com/oauth/token。
- 后台 /admin/connect-oauth 审计中能看到 authorize_redirect 和 token_exchange。
- redirect_uri 不匹配时客户端能清晰提示配置错误。