# 使用 LINUX DO Connect 登录：OAuth 2.0 接入指南（Golang）

**LINUX DO Connect** 提供标准 OAuth2 式授权与用户接口，官方入口为 [connect.linux.do](https://connect.linux.do)。本文说明其端点形态、在 Connect 中登记回调及 Go 侧接入方式，**与任意自建应用兼容**（不限定具体产品名）。

> 以 Connect 当前文档与控制台为准；若端点有变更，请以官网「应用接入」说明为准。

## 1. 协议与端点

对 **Connect 根地址** `BASE`（无尾斜杠，常见为 `https://connect.linux.do`）：


| 步骤      | 典型 URL                                                                 |
| ------- | ---------------------------------------------------------------------- |
| 授权      | `{BASE}/oauth2/authorize`                                              |
| 换 token | `{BASE}/oauth2/token`                                                  |
| 当前用户    | `{BASE}/api/user`（`Authorization: Bearer {access_token}`，Accept: JSON） |


Scope 以 Connect 应用接入要求为准，常见为读取用户信息类 scope（例如文档中的 `read:user` 等，以实际申请为准）。

## 2. 在 Connect 注册应用

1. 登录 [connect.linux.do](https://connect.linux.do)，在 **应用接入** 中创建应用。
2. **回调地址** 填写你服务的真实 `redirect_uri`（与下文 Go 中 `RedirectURL` 一致）。
3. 记录 **Client ID**、**Client Secret**。

## 3. Golang：`Endpoint` 配置

```go
import "golang.org/x/oauth2"

func linuxDoEndpoint(base string) oauth2.Endpoint {
	// 去掉 base 尾斜杠
	for len(base) > 0 && base[len(base)-1] == '/' {
		base = base[:len(base)-1]
	}
	return oauth2.Endpoint{
		AuthURL:  base + "/oauth2/authorize",
		TokenURL: base + "/oauth2/token",
	}
}
```

`oauth2.Config` 示例：

- `RedirectURL`：与 Connect 中登记的回调**完全一致**  
- `Scopes`：与创建应用时一致  
- 回调里：`cfg.Exchange(ctx, code)` 换 `access_token`

## 4. 拉取用户资料

成功换 token 后，请求：

- `GET {BASE}/api/user`  
- Header：`Authorization: Bearer {access_token}`

响应为 JSON。常见字段含用户 id、用户名、邮箱、头像等；**建议用返回的稳定 id 作为账号主键**（不要假设字段名永久不变，对接时以你抓包/文档为准）。

## 5. 网络与排障

- 换 token、访问 `/api/user` 由**你的服务器**发出；若机器无法访问 `connect.linux.do`（代理、墙、内网限制），会表现为超时或 `token exchange` 失败。  
- 浏览器能打开 Connect 授权页，不代表**后端**能连上 `token` URL；请在部署环境上测试出站 HTTPS。

## 6. 与 GitHub 示例同构的整合方式

实现步骤与 [github.md](github.md) 相同：根路径生成 `state` 并重定向到 `AuthCodeURL`；`oauth2/authorize` 的回调路径上取 `code`，`Exchange` 后带 Bearer 调 `/api/user`。仅替换：

- `oauth2.Config.Endpoint` 为 `linuxDoEndpoint(os.Getenv("LINUXDO_BASE"))`  
- 用户 JSON 的解析按 Connect 实际返回字段编写 `struct` 或 `map`。

## 7. 安全建议

- 校验 `state`；`Client Secret` 驻留服务端。  
- 对 Connect 用户 id 与本地用户做一对一绑定，并处理“该 id 已绑其他用户”的冲突。

