# Linux DO Connect OAuth(Open Authorization)是一个开放的网络授权标准,目前最新版本为 OAuth 2.0。我们日常使用的第三方登录(如 Google 账号登录)就采用了该标准。OAuth 允许用户授权第三方应用访问存储在其他服务提供商(如 Google)上的信息,无需在不同平台上重复填写注册信息。用户授权后,平台可以直接访问用户的账户信息进行身份验证,而用户无需向第三方应用提供密码。 目前系统已实现完整的 OAuth2 授权码(code)方式鉴权,但界面等配套功能还在持续完善中。让我们一起打造一个更完善的共享方案。 ## 基本介绍 这是一套标准的 OAuth2 鉴权系统,可以让开发者共享论坛的用户基本信息。 - 可获取字段: | 参数 | 说明 | | ----------------- | ------------------------------- | | `id` | 用户唯一标识(不可变) | | `username` | 论坛用户名 | | `name` | 论坛用户昵称(可变) | | `avatar_template` | 用户头像模板URL(支持多种尺寸) | | `active` | 账号活跃状态 | | `trust_level` | 信任等级(0-4) | | `silenced` | 禁言状态 | | `external_ids` | 外部ID关联信息 | | `api_key` | API访问密钥 | 通过这些信息,公益网站/接口可以实现: 1. 基于 `id` 的服务频率限制 2. 基于 `trust_level` 的服务额度分配 3. 基于用户信息的滥用举报机制 ## 相关端点 - Authorize 端点: `https://connect.linux.do/oauth2/authorize` - Token 端点:`https://connect.linux.do/oauth2/token` - 用户信息 端点:`https://connect.linux.do/api/user` ## 申请使用 - 访问 [Connect.Linux.Do](https://connect.linux.do/) 申请接入你的应用。 ![linuxdoconnect_1](https://wiki.linux.do/_next/image?url=%2Flinuxdoconnect_1.png&w=1080&q=75) - 点击 **`我的应用接入`** - **`申请新接入`**,填写相关信息。其中 **`回调地址`** 是你的应用接收用户信息的地址。 ![linuxdoconnect_2](https://wiki.linux.do/_next/image?url=%2Flinuxdoconnect_2.png&w=1080&q=75) - 申请成功后,你将获得 **`Client Id`** 和 **`Client Secret`**,这是你应用的唯一身份凭证。 ![linuxdoconnect_3](https://wiki.linux.do/_next/image?url=%2Flinuxdoconnect_3.png&w=1080&q=75) ## 接入 Linux Do JavaScript ```JavaScript // 安装第三方请求库(或使用原生的 Fetch API),本例中使用 axios // npm install axios // 通过 OAuth2 获取 Linux Do 用户信息的参考流程 const axios = require('axios'); const readline = require('readline'); // 配置信息(建议通过环境变量配置,避免使用硬编码) const CLIENT_ID = '你的 Client ID'; const CLIENT_SECRET = '你的 Client Secret'; const REDIRECT_URI = '你的回调地址'; const AUTH_URL = 'https://connect.linux.do/oauth2/authorize'; const TOKEN_URL = 'https://connect.linux.do/oauth2/token'; const USER_INFO_URL = 'https://connect.linux.do/api/user'; // 第一步:生成授权 URL function getAuthUrl() { const params = new URLSearchParams({ client_id: CLIENT_ID, redirect_uri: REDIRECT_URI, response_type: 'code', scope: 'user' }); return `${AUTH_URL}?${params.toString()}`; } // 第二步:获取 code 参数 function getCode() { return new Promise((resolve) => { // 本例中使用终端输入来模拟流程,仅供本地测试 // 请在实际应用中替换为真实的处理逻辑 const rl = readline.createInterface({ input: process.stdin, output: process.stdout }); rl.question('从回调 URL 中提取出 code,粘贴到此处并按回车:', (answer) => { rl.close(); resolve(answer.trim()); }); }); } // 第三步:使用 code 参数获取访问令牌 async function getAccessToken(code) { try { const form = new URLSearchParams({ client_id: CLIENT_ID, client_secret: CLIENT_SECRET, code: code, redirect_uri: REDIRECT_URI, grant_type: 'authorization_code' }).toString(); const response = await axios.post(TOKEN_URL, form, { // 提醒:需正确配置请求头,否则无法正常获取访问令牌 headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' } }); return response.data; } catch (error) { console.error(`获取访问令牌失败:${error.response ? JSON.stringify(error.response.data) : error.message}`); throw error; } } // 第四步:使用访问令牌获取用户信息 async function getUserInfo(accessToken) { try { const response = await axios.get(USER_INFO_URL, { headers: { Authorization: `Bearer ${accessToken}` } }); return response.data; } catch (error) { console.error(`获取用户信息失败:${error.response ? JSON.stringify(error.response.data) : error.message}`); throw error; } } // 主流程 async function main() { // 1. 生成授权 URL,前端引导用户访问授权页 const authUrl = getAuthUrl(); console.log(`请访问此 URL 授权:${authUrl} `); // 2. 用户授权后,从回调 URL 获取 code 参数 const code = await getCode(); try { // 3. 使用 code 参数获取访问令牌 const tokenData = await getAccessToken(code); const accessToken = tokenData.access_token; // 4. 使用访问令牌获取用户信息 if (accessToken) { const userInfo = await getUserInfo(accessToken); console.log(` 获取用户信息成功:${JSON.stringify(userInfo, null, 2)}`); } else { console.log(` 获取访问令牌失败:${JSON.stringify(tokenData)}`); } } catch (error) { console.error('发生错误:', error); } } ``` Python ```python # 安装第三方请求库,本例中使用 requests # pip install requests # 通过 OAuth2 获取 Linux Do 用户信息的参考流程 import requests import json # 配置信息(建议通过环境变量配置,避免使用硬编码) CLIENT_ID = '你的 Client ID' CLIENT_SECRET = '你的 Client Secret' REDIRECT_URI = '你的回调地址' AUTH_URL = 'https://connect.linux.do/oauth2/authorize' TOKEN_URL = 'https://connect.linux.do/oauth2/token' USER_INFO_URL = 'https://connect.linux.do/api/user' # 第一步:生成授权 URL def get_auth_url(): params = { 'client_id': CLIENT_ID, 'redirect_uri': REDIRECT_URI, 'response_type': 'code', 'scope': 'user' } auth_url = f"{AUTH_URL}?{'&'.join(f'{k}={v}' for k, v in params.items())}" return auth_url # 第二步:获取 code 参数 def get_code(): # 本例中使用终端输入来模拟流程,仅供本地测试 # 请在实际应用中替换为真实的处理逻辑 return input('从回调 URL 中提取出 code,粘贴到此处并按回车:').strip() # 第三步:使用 code 参数获取访问令牌 def get_access_token(code): try: data = { 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'code': code, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code' } # 提醒:需正确配置请求头,否则无法正常获取访问令牌 headers = { 'Content-Type': 'application/x-www-form-urlencoded', 'Accept': 'application/json' } response = requests.post(TOKEN_URL, data=data, headers=headers) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"获取访问令牌失败:{e}") return None # 第四步:使用访问令牌获取用户信息 def get_user_info(access_token): try: headers = { 'Authorization': f'Bearer {access_token}' } response = requests.get(USER_INFO_URL, headers=headers) response.raise_for_status() return response.json() except requests.exceptions.RequestException as e: print(f"获取用户信息失败:{e}") return None # 主流程 if __name__ == '__main__': # 1. 生成授权 URL,前端引导用户访问授权页 auth_url = get_auth_url() print(f'请访问此 URL 授权:{auth_url} ') # 2. 用户授权后,从回调 URL 获取 code 参数 code = get_code() # 3. 使用 code 参数获取访问令牌 token_data = get_access_token(code) if token_data: access_token = token_data.get('access_token') # 4. 使用访问令牌获取用户信息 if access_token: user_info = get_user_info(access_token) if user_info: print(f" 获取用户信息成功:{json.dumps(user_info, indent=2)}") else: print(" 获取用户信息失败") else: print(f" 获取访问令牌失败:{json.dumps(token_data, indent=2)}") else: print(" 获取访问令牌失败") ``` PHP ```php // 通过 OAuth2 获取 Linux Do 用户信息的参考流程 // 配置信息 $CLIENT_ID = '你的 Client ID'; $CLIENT_SECRET = '你的 Client Secret'; $REDIRECT_URI = '你的回调地址'; $AUTH_URL = 'https://connect.linux.do/oauth2/authorize'; $TOKEN_URL = 'https://connect.linux.do/oauth2/token'; $USER_INFO_URL = 'https://connect.linux.do/api/user'; // 生成授权 URL function getAuthUrl($clientId, $redirectUri) { global $AUTH_URL; return $AUTH_URL . '?' . http_build_query([ 'client_id' => $clientId, 'redirect_uri' => $redirectUri, 'response_type' => 'code', 'scope' => 'user' ]); } // 使用 code 参数获取用户信息(合并获取令牌和获取用户信息的步骤) function getUserInfoWithCode($code, $clientId, $clientSecret, $redirectUri) { global $TOKEN_URL, $USER_INFO_URL; // 1. 获取访问令牌 $ch = curl_init($TOKEN_URL); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ 'client_id' => $clientId, 'client_secret' => $clientSecret, 'code' => $code, 'redirect_uri' => $redirectUri, 'grant_type' => 'authorization_code' ])); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Content-Type: application/x-www-form-urlencoded', 'Accept: application/json' ]); $tokenResponse = curl_exec($ch); curl_close($ch); $tokenData = json_decode($tokenResponse, true); if (!isset($tokenData['access_token'])) { return ['error' => '获取访问令牌失败', 'details' => $tokenData]; } // 2. 获取用户信息 $ch = curl_init($USER_INFO_URL); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $tokenData['access_token'] ]); $userResponse = curl_exec($ch); curl_close($ch); return json_decode($userResponse, true); } // 主流程 // 1. 生成授权 URL $authUrl = getAuthUrl($CLIENT_ID, $REDIRECT_URI); echo "使用 Linux Do 登录"; // 2. 处理回调并获取用户信息 if (isset($_GET['code'])) { $userInfo = getUserInfoWithCode( $_GET['code'], $CLIENT_ID, $CLIENT_SECRET, $REDIRECT_URI ); if (isset($userInfo['error'])) { echo '错误: ' . $userInfo['error']; } else { echo '欢迎, ' . $userInfo['name'] . '!'; // 处理用户登录逻辑... } } ``` ## 使用说明 ### 授权流程 1. 用户点击应用中的’使用 Linux Do 登录’按钮 2. 系统将用户重定向至 Linux Do 的授权页面 3. 用户完成授权后,系统自动重定向回应用并携带授权码 4. 应用使用授权码获取访问令牌 5. 使用访问令牌获取用户信息 ### 安全建议 - 切勿在前端代码中暴露 Client Secret - 对所有用户输入数据进行严格验证 - 确保使用 HTTPS 协议传输数据 - 定期更新并妥善保管 Client Secret