
在数字化转型加速的今天,单点登录(SSO)已成为企业身份管理的核心基础设施。袋鼠云UED团队在过去几年中,为金融、政务、医疗等领域的大型系统构建SSO解决方案。本文将分享基于Token的标准SSO实现,同时解密UED团队对于单点登录的安全实践方式。
单点登录核心原理
SSO的基本工作流程
双Token机制的优势Access Token:短期有效(通常1-2小时),减少泄露风险 Refresh Token:长期有效(通常7-30天),存储于HttpOnly Cookie中 安全平衡:即使Access Token泄露,攻击者也难以获取新的有效Token

Node.js + JWT实现示例
认证服务核心代码const jwt = require('jsonwebtoken');const crypto = require('crypto');// 生成密钥对(实际项目应该预生成并妥善保存)const { privateKey, publicKey } = crypto.generateKeyPairSync('rsa', {modulusLength: 2048,});// 生成Tokenfunction generateTokens(user) {const accessToken = jwt.sign({ userId: user.id, role: user.role },privateKey,{ algorithm: 'RS256', expiresIn: '1h' });const refreshToken = jwt.sign({ userId: user.id, tokenVersion: user.tokenVersion },privateKey,{ algorithm: 'RS256', expiresIn: '7d' });return { accessToken, refreshToken };}// 验证中间件function authenticate(req, res, next) {const authHeader = req.headers['authorization'];const token = authHeader && authHeader.split(' ')[1];if (!token) return res.sendStatus(401);jwt.verify(token, publicKey, (err, user) => {if (err) return res.sendStatus(403);req.user = user;next();});}
Token刷新接口设计app.post('/refresh-token', (req, res) => {const refreshToken = req.cookies.refreshToken;if (!refreshToken) return res.sendStatus(401);jwt.verify(refreshToken, publicKey, async (err, payload) => {if (err) return res.sendStatus(403);// 检查数据库中的token版本(防止被盗用)const user = await User.findById(payload.userId);if (user.tokenVersion !== payload.tokenVersion) {return res.sendStatus(403);}// 颁发新Tokenconst newTokens = generateTokens(user);// 设置HttpOnly Cookieres.cookie('refreshToken', newTokens.refreshToken, {httpOnly: true,secure: true,sameSite: 'strict',maxAge: 7 * 24 * 60 * 60 * 1000});res.json({ accessToken: newTokens.accessToken });});});

前端实现关键点
Axios拦截器配置const api = axios.create({baseURL: process.env.API_URL,});// 请求拦截器api.interceptors.request.use(config => {const token = localStorage.getItem('accessToken');if (token) {config.headers.Authorization = `Bearer ${token}`;}return config;});// 响应拦截器api.interceptors.response.use(response => response,async error => {const originalRequest = error.config;// 401错误且不是刷新请求if (error.response.status === 401 && !originalRequest._retry) {originalRequest._retry = true;try {const { data } = await axios.post('/refresh-token', {}, {withCredentials: true // 携带cookie});localStorage.setItem('accessToken', data.accessToken);originalRequest.headers.Authorization = `Bearer ${data.accessToken}`;return api(originalRequest);} catch (refreshError) {// 刷新失败跳转登录window.location = '/login';return Promise.reject(refreshError);}}return Promise.reject(error);});
安全存储方案对比存储方式 | 优点 | 缺点 | 适用场景 |
localStorage | 容量大、易用 | XSS风险 | Access Token |
sessionStorage | 标签页隔离 | 关闭失效 | 临时会话 |
HttpOnly Cookie | 防XSS | CSRF风险 | Refresh Token |
内存变量 | 最安全 | 刷新丢失 | 敏感操作 |

安全增强措施
Token撤销策略// 用户模型增加字段const userSchema = new mongoose.Schema({tokenVersion: {type: Number,default: 0},// 其他字段...});// 密码修改时增加版本号userSchema.methods.invalidateTokens = function() {this.tokenVersion += 1;return this.save();};
多因素认证集成
app.post('/login', async (req, res) => {const { email, password } = req.body;const user = await User.findOne({ email });if (!user || !await bcrypt.compare(password, user.password)) {return res.status(401).send('认证失败');}// 检查是否开启MFAif (user.mfaEnabled) {const tempToken = jwt.sign({ userId: user.id, mfa: true },privateKey,{ expiresIn: '5m' });return res.json({ mfaRequired: true, tempToken });}// 常规登录流程const tokens = generateTokens(user);sendTokens(res, tokens);});app.post('/verify-mfa', authenticateTempToken, (req, res) => {const { code } = req.body;if (verifyMfaCode(req.user.userId, code)) {const user = await User.findById(req.user.userId);const tokens = generateTokens(user);sendTokens(res, tokens);} else {res.status(401).send('MFA验证失败');}});

最佳实践建议
传输安全始终使用HTTPS 设置 Secure
和SameSite
Cookie属性
防御措施实现CSRF Token机制 设置速率限制(如1分钟5次刷新)
监控审计// 记录Token使用情况function logTokenUsage(token, action) {const payload = jwt.decode(token);AuditLog.create({userId: payload.userId,action,ip: req.ip,userAgent: req.headers['user-agent']});}
失效处理登出时清除客户端Token 服务端维护短期黑名单(JWT本身无状态)
Token与Refresh Token机制为现代SSO提供了优雅的解决方案。作为袋鼠云技术团队,我们在多个项目中验证了这一架构的可靠性,Token+RefreshToken方案在安全性和用户体验之间取得了良好平衡。实际部署时还需要考虑:
分布式环境下的密钥管理 多平台Token同步 会话超时策略
建议结合OAuth 2.0或OpenID Connect等标准协议实现生产级SSO系统。

点击阅读全文,申请产品试用文章转载自数栈研习社,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。





