有后端的网站
快速上手:有后端的网站(授权码 + client_secret)
适用:任何有服务端的站点(Node、PHP、Rust、Cloudflare Workers……)。授权码由你的 服务端换取,client_secret 永远不经过浏览器。
前置:在 开发者平台 创建应用时选「有后端(机密客户端)」,登记回调地址 (如 https://app.example.com/auth/callback),创建时显示的 client_secret 只出现一次, 存进你的环境变量。
安装
npm install @geekhonize/sso-sdkimport { 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_error | SSO 返回 {ok:false}(授权码无效/过期、secret 不对…) | 看 err.message(中文)与 err.status |
sso_bad_response | 拿到的不是 JSON | Cloudflare 错误页。同 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。