快速开始

5 分钟完成开发者注册、创建应用、OAuth 2.1 授权全流程。

第 1 步:注册开发者账号

访问 open.yunjii.cn/console

  • 已有云集账号 → 直接登录
  • 新用户 → 点击「注册」,使用微信扫码或手机号注册

登录后系统自动创建开发者档案,进入控制台。

开发者账号基于云集统一身份(UM),一个账号通行全家族。

第 2 步:创建应用

在控制台进入「应用」页面,点击「新建应用」:

字段说明
应用名称你的应用的显示名称
描述(可选)应用的简要说明,开发者后台展示

创建成功后,你会获得一对凭证:

  • AppKeyak_ 开头)— 应用的公开标识
  • AppSecretas_ 开头)— 仅展示一次,请立即保存

AppSecret 是你应用的密钥,切忌暴露在客户端代码中。纯前端应用应使用 PKCE 流程(无需 Secret)。

第 3 步:配置回调地址

在应用详情页,配置你的 OAuth 回调地址(callbackUrls):

https://yourapp.com/api/auth/callback

这是用户授权后浏览器重定向的地址,必须与你的应用实际地址一致。

第 4 步:引导用户授权

使用 OAuth 2.1 Authorization Code + PKCE 流程(推荐,无需 AppSecret)。

生成 PKCE 参数

在你的后端生成 code_verifiercode_challenge

// Node.js 示例
const crypto = require('crypto');

const verifier = crypto.randomBytes(32).toString('base64url');
const challenge = crypto
  .createHash('sha256')
  .update(verifier)
  .digest('base64url');

// 保存 verifier 到会话(回调时需要)
sessionStorage.setItem('code_verifier', verifier);

构造授权 URL

https://open.yunjii.cn/oauth/authorize?
  response_type=code&
  client_id=ak_YOUR_APP_KEY&
  redirect_uri=https://yourapp.com/callback&
  scope=openid%20profile&
  state=RANDOM_CSRF_TOKEN&
  code_challenge_method=S256&
  code_challenge=YOUR_CHALLENGE
参数说明
response_type固定 code
client_id你的 AppKey
redirect_uri必须与注册的回调地址一致
scope请求的权限范围
stateCSRF 防护,随机字符串,回调时需校验
code_challenge_method固定 S256
code_challenge上面生成的 challenge 值

将用户浏览器重定向到此 URL。用户完成登录/授权后,浏览器会重定向回你的 redirect_uri,携带 code 参数。

第 5 步:交换 Access Token

在回调端点,用 code 兑换 token:

curl -X POST "https://open.yunjii.cn/oauth/token" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code&
       code=AUTH_CODE&
       redirect_uri=https://yourapp.com/callback&
       code_verifier=YOUR_VERIFIER"

成功响应:

{
  "access_token": "eyJhbGci...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "eyJhbGci..."
}

第 6 步:调用 API

使用 access_token 调用用户信息 API:

curl -H "Authorization: Bearer eyJhbGci..." \
  "https://open.yunjii.cn/user/profile"

完整代码示例

Node.js + Express

const express = require('express');
const crypto = require('crypto');
const app = express();

// PKCE 参数
const verifier = crypto.randomBytes(32).toString('base64url');
const challenge = crypto.createHash('sha256').update(verifier).digest('base64url');

// 1. 跳转到授权页
app.get('/login', (req, res) => {
  const params = new URLSearchParams({
    response_type: 'code',
    client_id: process.env.APP_KEY,
    redirect_uri: 'http://localhost:3000/callback',
    scope: 'openid profile',
    state: crypto.randomBytes(16).toString('hex'),
    code_challenge_method: 'S256',
    code_challenge: challenge,
  });
  res.redirect(`https://open.yunjii.cn/oauth/authorize?${params}`);
});

// 2. 回调处理
app.get('/callback', async (req, res) => {
  const { code } = req.query;
  const tokenResp = await fetch('https://open.yunjii.cn/oauth/token', {
    method: 'POST',
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    body: new URLSearchParams({
      grant_type: 'authorization_code',
      code,
      redirect_uri: 'http://localhost:3000/callback',
      code_verifier: verifier,
    }),
  });
  const token = await tokenResp.json();
  // token.access_token — 保存到会话
  res.json(token);
});

下一步