跳到主要内容

有后端的网站

快速上手:有后端的网站(授权码 + client_secret)

适用:任何有服务端的站点(Node、PHP、Rust、Cloudflare Workers……)。授权码由你的 服务端换取,client_secret 永远不经过浏览器。

前置:在 开发者平台 创建应用时选「有后端(机密客户端)」,登记回调地址 (如 https://app.example.com/auth/callback),创建时显示的 client_secret 只出现一次, 存进你的环境变量。

安装

npm install @geekhonize/sso-sdk
import { createSsoClient } from '@geekhonize/sso-sdk/server';

const sso = createSsoClient({
  clientId: process.env.SSO_CLIENT_ID,
  clientSecret: process.env.SSO_CLIENT_SECRET,
  sessionSecret: process.env.SESSION_SECRET, // 本站自签会话 cookie 用(与 SSO 无关)
});

三条路由

// 1) /login —— 跳转授权(state 自己生成并写进签名 cookie / session 防 CSRF)
const state = randomToken(32);
app.get('/login', (req, res) => {
  req.session.oauthState = state;
  res.redirect(sso.buildAuthorizeUrl({
    redirectUri: 'https://app.example.com/auth/callback',
    state,
  }));
});

// 2) /auth/callback —— 校验 state → 换令牌 → 建立本站会话
app.get('/auth/callback', async (req, res) => {
  const { code, state: got, error } = sso.parseCallback(`${req.protocol}://${req.get('host')}${req.originalUrl}`);
  if (error || !code || got !== req.session.oauthState) return res.redirect('/login?error=bad_state');
  const { session, cookie } = await sso.establishSession({ code });
  res.setHeader('set-cookie', cookie);       // httpOnly 自签会话
  res.redirect('/');
});

// 3) /logout
app.get('/logout', (req, res) => {
  res.setHeader('set-cookie', sso.clearSessionCookie());
  res.redirect('/');
});

每个请求:验会话 + 定期复核

app.use(async (req, res, next) => {
  req.gh = await sso.readSession(req.headers.cookie || '');
  next();
});

// 会话 cookie 只防篡改。令牌真值必须回源:
const me = await sso.me(session.token);   // 401/403 = 账号已失效,清会话

建议按官网的做法:每 ~30 分钟回源 me() 复核一次,SSO 侧封号/降权最迟半小时内生效。

错误分类

SDK 抛的错误带 code 字段:

code含义处理
sso_errorSSO 返回 {ok:false}(授权码无效/过期、secret 不对…)看 err.message(中文)与 err.status
sso_bad_response拿到的不是 JSONCloudflare 错误页。同 zone 部署必查 Service Binding,见下
(网络异常)fetch 抛出SSO 不可达,稍后重试

⚠ Cloudflare Workers 同 zone 必读:如果你的 Worker 与 auth.geekhonize.top 同 zone, 服务端 fetch() 调 SSO 会被 Cloudflare 拒绝(error 1042)。必须配 [[services]] Service Binding 并把 env.SSO.fetch 注入 SDK —— 详见 Workers 接入。

完整示例见 SDK 仓库 examples/node/server.mjs。

本页内容随 SDK 版本发布。发现错误请到 SDK 仓库 提 issue。