标题:JWT 实现单点登录的详细流程与实践
一、引言
在当今的互联网应用中,单点登录(Single Sign-On,SSO)成为了提高用户体验和管理用户身份的重要方式,JWT(JSON Web Token)作为一种轻量级的认证方式,被广泛应用于实现单点登录,本文将详细介绍 JWT 单点登录的流程,并通过实际代码示例展示其实现过程。
二、JWT 单点登录流程
1、用户访问应用系统 A,系统 A 检测到用户未登录,跳转到登录页面。
2、用户在登录页面输入用户名和密码,提交登录请求。
3、应用系统 A 将用户的登录信息发送到认证服务器进行验证。
4、认证服务器验证用户信息成功后,生成一个 JWT 令牌,并将其返回给应用系统 A。
5、应用系统 A 将 JWT 令牌存储在用户的会话中或 Cookie 中,并跳转到应用系统 A 的首页。
6、用户在应用系统 A 中进行操作时,应用系统 A 会在每次请求中携带 JWT 令牌。
7、应用系统 A 将 JWT 令牌发送到资源服务器进行验证。
8、资源服务器验证 JWT 令牌成功后,允许用户访问相应的资源。
9、用户退出应用系统 A 时,应用系统 A 将 JWT 令牌删除。
三、JWT 单点登录的实现
1、安装依赖
我们需要安装jsonwebtoken
库,用于生成和验证 JWT 令牌,可以使用以下命令安装:
npm install jsonwebtoken
2、创建认证服务器
创建一个认证服务器,用于验证用户的登录信息,并生成 JWT 令牌,以下是一个简单的 Node.js 示例代码:
const jwt = require('jsonwebtoken'); // 生成 JWT 令牌 function generateToken(payload) { return jwt.sign(payload, 'your-secret-key', { expiresIn: '1h' }); } // 验证 JWT 令牌 function verifyToken(token) { return jwt.verify(token, 'your-secret-key'); } // 模拟用户登录 function login(username, password) { // 这里可以根据实际情况进行用户验证 if (username === 'admin' && password === '123456') { const payload = { username }; const token = generateToken(payload); return token; } else { return null; } } module.exports = { generateToken, verifyToken, login };
在上述代码中,我们定义了三个函数:generateToken
用于生成 JWT 令牌,verifyToken
用于验证 JWT 令牌,login
用于模拟用户登录。your-secret-key
是一个密钥,用于签名和验证 JWT 令牌。
3、创建应用系统 A
创建一个应用系统 A,用于处理用户的登录请求,并将 JWT 令牌存储在用户的会话中或 Cookie 中,以下是一个简单的 Node.js 示例代码:
const express = require('express'); const app = express(); const jwt = require('jsonwebtoken'); const authService = require('./auth-service'); // 设置会话中间件 app.use(express.session({ secret:'session-secret', resave: false, saveUninitialized: true })); // 登录路由 app.post('/login', async (req, res) => { const { username, password } = req.body; const token = await authService.login(username, password); if (token) { // 将 JWT 令牌存储在会话中 req.session.token = token; res.send({ message: '登录成功' }); } else { res.send({ message: '登录失败' }); } }); // 保护路由 app.get('/protected', ensureAuthenticated, (req, res) => { res.send({ message: '访问 protected 资源成功' }); }); // 确保用户已登录的中间件 function ensureAuthenticated(req, res, next) { const token = req.session.token; if (token) { try { const payload = jwt.verify(token, 'your-secret-key'); req.user = payload; next(); } catch (error) { res.send({ message: '会话已过期,请重新登录' }); } } else { res.send({ message: '未登录,请先登录' }); } } app.listen(3000, () => { console.log('应用系统 A 正在监听 3000 端口...'); });
在上述代码中,我们使用了 Express 框架创建了一个应用系统 A,我们设置了会话中间件,用于存储 JWT 令牌,我们定义了一个登录路由,用于处理用户的登录请求,我们还定义了一个保护路由,用于保护需要登录才能访问的资源。ensureAuthenticated
中间件用于确保用户已登录。
4、创建资源服务器
创建一个资源服务器,用于验证 JWT 令牌,并返回相应的资源,以下是一个简单的 Node.js 示例代码:
const express = require('express'); const app = express(); const jwt = require('jsonwebtoken'); const authService = require('./auth-service'); // 保护路由 app.get('/resource', ensureAuthenticated, (req, res) => { res.send({ message: '访问资源成功' }); }); // 确保用户已登录的中间件 function ensureAuthenticated(req, res, next) { const token = req.headers.authorization.split(' ')[1]; if (token) { try { const payload = jwt.verify(token, 'your-secret-key'); req.user = payload; next(); } catch (error) { res.send({ message: '令牌无效,请重新登录' }); } } else { res.send({ message: '未授权访问' }); } } app.listen(4000, () => { console.log('资源服务器正在监听 4000 端口...'); });
在上述代码中,我们使用了 Express 框架创建了一个资源服务器,我们定义了一个保护路由,用于保护需要登录才能访问的资源。ensureAuthenticated
中间件用于确保用户已登录。
5、测试
启动认证服务器、应用系统 A 和资源服务器,然后访问应用系统 A 的登录页面,输入用户名和密码进行登录,登录成功后,访问应用系统 A 的 protected 路由和资源服务器的 resource 路由,应该能够成功访问相应的资源。
四、总结
本文介绍了 JWT 单点登录的流程,并通过实际代码示例展示了其实现过程,JWT 单点登录可以提高用户体验和管理用户身份,是一种非常实用的技术,在实际应用中,我们可以根据具体需求进行定制和扩展。
评论列表