概述
X-GORB OAuth 2.0 为第三方应用程序提供安全的身份验证和授权服务。本指南提供了将"使用X-GORB登录"功能集成到您应用程序所需的全部信息。
为什么选择X-GORB OAuth?
行业标准
完全符合OAuth 2.0标准,支持授权码模式(Authorization Code Grant)
增强安全性
支持可选的双因素认证(2FA)、PKCE协议,具备state参数防护功能
丰富的用户数据
可访问经过验证的电子邮件、个人资料信息和头像
无需存储密码
无需处理用户密码——身份验证由我们统一管理
全球基础设施
全球分布的低延迟身份验证端点
快速开始
1. 注册您的应用程序
访问 X-GORB开发者控制台 创建您的OAuth应用程序。
所需信息:
- 应用程序名称
- 主页URL
- 回调URL(重定向URI)
- 应用程序图标(可选,推荐提供)
审核通过后,您将收到:
- 客户端ID(Client ID):
7d2f153dcb132991f9ae1b6610b6f279(示例) - 客户端密钥(Client Secret):请妥善保管,切勿在客户端代码中暴露
2. 三步集成
// 步骤1:将用户重定向至X-GORB
$authUrl = "https://so.xgorb.cn/users/oauth/authorize.php";
$params = [
'client_id' => '您的客户端ID',
'redirect_uri' => 'https://yourapp.com/callback',
'response_type' => 'code',
'scope' => 'openid profile email',
'state' => bin2hex(random_bytes(16))
];
header('Location: ' . $authUrl . '?' . http_build_query($params));
// 步骤2:处理回调,通过授权码换取令牌
$code = $_GET['code'];
$token = exchangeCodeForToken($code);
// 步骤3:获取用户信息
$user = fetchUserInfo($token['access_token']);
端点参考
授权端点
GET https://so.xgorb.cn/users/oauth/authorize.php
| 参数 | 是否必填 | 描述 |
|---|---|---|
| client_id | ✅ | 您应用程序的客户端ID |
| redirect_uri | ✅ | 必须与您注册的其中一个回调URL完全匹配 |
| response_type | ✅ | 使用 code 表示授权码模式 |
| scope | ✅ | 以空格分隔的请求权限列表 |
| state | ✅ | 随机字符串,用于防止跨站请求伪造(CSRF)攻击 |
令牌端点
POST https://so.xgorb.cn/users/oauth/token.php
Content-Type: application/x-www-form-urlencoded
| 参数 | 是否必填 | 描述 |
|---|---|---|
| grant_type | ✅ | 使用 authorization_code 或 refresh_token |
| client_id | ✅ | 您的客户端ID |
| client_secret | ✅ | 您的客户端密钥 |
| code | ✅* | 授权码(适用于authorization_code模式) |
| redirect_uri | ✅* | 与授权请求中使用的URI一致 |
| refresh_token | ✅* | 刷新令牌(适用于refresh_token模式) |
成功响应:
{
"access_token": "a1b2c3d4e5f6...",
"refresh_token": "r1e2f3r4e5s6h7...",
"token_type": "Bearer",
"expires_in": 3600
}
用户信息端点
GET https://so.xgorb.cn/users/oauth/userinfo.php
Authorization: Bearer {access_token}
成功响应:
{
"sub": "123456789",
"name": "John Doe",
"given_name": "John",
"family_name": "Doe",
"email": "john@example.com",
"email_verified": true,
"picture": "https://so.xgorb.cn/avatars/123456789.jpg",
"updated_at": "2026-04-18T10:30:00Z"
}
可用权限范围(Scope)
| 权限范围 | 描述 | 用户同意提示文本 |
|---|---|---|
| openid | 用户唯一标识符 | "了解您在X-GORB上的身份" |
| profile | 基本个人资料信息 | "查看您的姓名和头像" |
| 电子邮件地址 | "查看您的电子邮件地址" | |
| developer.read | 开发者状态(只读) | "查看您的开发者状态" |
默认权限范围:如果未指定权限范围,将仅授予 openid 权限。
完整集成示例
PHP(后端)
<?php
class XGORBOAuthClient {
private $clientId; private $clientSecret; private $redirectUri;
private $authUrl = 'https://so.xgorb.cn/users/oauth/authorize.php';
private $tokenUrl = 'https://so.xgorb.cn/users/oauth/token.php';
private $userInfoUrl = 'https://so.xgorb.cn/users/oauth/userinfo.php';
public function __construct($clientId, $clientSecret, $redirectUri) {
$this->clientId = $clientId; $this->clientSecret = $clientSecret; $this->redirectUri = $redirectUri;
}
public function getAuthorizationUrl($state = null) {
$state = $state ?? bin2hex(random_bytes(16));
$_SESSION['oauth_state'] = $state;
$params = ['client_id' => $this->clientId, 'redirect_uri' => $this->redirectUri, 'response_type' => 'code', 'scope' => 'openid profile email', 'state' => $state];
return $this->authUrl . '?' . http_build_query($params);
}
public function getAccessToken($code) { /* 实现省略 */ }
public function refreshAccessToken($refreshToken) { /* 实现省略 */ }
public function getUserInfo($accessToken) { /* 实现省略 */ }
}
?>
JavaScript(带后端代理的前端)
class XGORBOAuthClient {
constructor(config) { this.clientId = config.clientId; this.redirectUri = config.redirectUri; }
login() { /* 生成state并跳转 */ }
async handleCallback() { /* 通过后端代理交换令牌 */ }
isAuthenticated() { /* 检查本地存储 */ }
logout() { /* 清除本地存储 */ }
}
Python(Flask)
import requests, secrets
from flask import Flask, redirect, request, session
@app.route('/login')
def login():
state = secrets.token_urlsafe(16)
session['oauth_state'] = state
params = {'client_id': CLIENT_ID, 'redirect_uri': REDIRECT_URI, 'response_type': 'code', 'scope': 'openid profile email', 'state': state}
return redirect(f"{AUTH_URL}?{urlencode(params)}")
@app.route('/callback')
def callback():
# 验证state并交换令牌,获取用户信息
pass
Node.js(Express)
const express = require('express');
const crypto = require('crypto');
const axios = require('axios');
app.get('/login', (req, res) => {
const state = crypto.randomBytes(16).toString('hex');
req.session.oauthState = state;
const params = new URLSearchParams({ client_id, redirect_uri, response_type: 'code', scope: 'openid profile email', state });
res.redirect(`${authUrl}?${params.toString()}`);
});
app.get('/callback', async (req, res) => {
const { code, state } = req.query;
// 交换令牌并获取用户信息
});
错误处理
常见错误代码
| 错误代码 | 描述 | 推荐操作 |
|---|---|---|
| invalid_request | 请求参数格式错误 | 验证所有必填参数是否齐全 |
| invalid_client | 客户端身份验证失败 | 检查客户端ID和客户端密钥 |
| invalid_grant | 授权码或刷新令牌无效 | 请求新的授权码 |
| unsupported_grant_type | 不支持的授权模式 | 使用authorization_code或refresh_token模式 |
| access_denied | 用户拒绝授权 | 优雅处理——用户取消了登录操作 |
| redirect_uri_mismatch | 回调URL与注册的URI不匹配 | 确保回调URL与注册的URL完全一致 |
错误响应格式:
{
"error": "invalid_grant",
"error_description": "授权码已过期"
}