1. 简介
单点登录「SSO」是一种常见的身份认证方式,能够方便地在多个系统之间共享用户身份信息,提高用户体验和安全性。本文将介绍如何使用Node.js实现单点登录的应用场景。
2. 基础知识
在介绍实现单点登录之前,我们需要了解以下基础知识。
2.1 Cookie 和 Session
Cookie 和 Session 都是用于在浏览器和服务器之间存储信息的机制。 Cookie 是一种存储在客户端浏览器中的小文本文件,用于存储用户身份验证信息、用户喜好设置等;Session 是一种存储在服务器上的数据结构,用于存储用户的会话信息。
当用户登录到系统 A 后,系统 A 将生成一个 Session,并将 Session ID 存储在 Cookie 中发送给浏览器。浏览器在访问其他系统 B、C 时,会带上 Cookie 中的 Session ID,系统 B、C 就能通过该 Session ID 获取用户的身份信息和操作权限,实现单点登录效果。
2.2 JWT
JWT(JSON Web Token)是一种用于身份认证和授权的标准化方法,可以在不同系统之间共享用户身份信息。
其工作原理是,当用户登录成功时,系统将生成一个包含用户信息和签名的 Token,并将该 Token 发送到客户端。客户端在访问其他系统时,会带上该 Token,其他系统则通过检查 Token 来确认用户的身份信息和权限。
3. 实现单点登录
3.1 统一认证中心
单点登录的核心是一个统一认证中心(Central Authentication Service,简称CAS),用于管理用户的身份验证和授权信息。
CAS 的工作流程如下:
1. 用户访问需要登录的应用系统;
2. 应用系统检查用户是否已经登录过,若未登录,则重定向到 CAS;
3. CAS 识别用户身份并生成一个 Ticket,然后将 Ticket 发送回应用系统;
4. 应用系统用 Ticket 向 CAS 进行验证,若 Ticket 有效,则建立用户会话。
3.2 Node.js 实现 CAS
下面介绍如何使用 Node.js 实现 CAS。
3.2.1 安装依赖
npm install express express-session body-parser ejs --save
在这里我们引入 Express 框架、express-session中间件、body-parser 中间件和 EJS 模板引擎。
3.2.2 编写代码
以下是实现 CAS 的代码。
const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');
const ejs = require('ejs');
const app = express();
//设置session中间件
app.use(session({
secret: 'casNode',
resave: false,
saveUninitialized: true
}));
//设置body-parser中间件
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({
extended: true
}));
//设置模板引擎
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
//设置路由
app.get('/', (req, res) => {
res.render('index');
});
app.post('/login', (req, res) => {
let username = req.body.username;
let password = req.body.password;
//TODO: 验证用户名和密码是否正确
if (username === 'admin' && password === 'admin') {
req.session.user = { username: 'admin' };
res.redirect('/home');
} else {
res.redirect('/');
}
});
app.get('/home', (req, res) => {
if (req.session.user) {
res.render('home', { user: req.session.user });
} else {
res.redirect('/');
}
});
app.listen(3000);
3.2.3 页面模板
在模板引擎中,我们可以用<% %>
来表示逻辑代码,<%= %>
来表示输出内容。
下面是模板文件 index.ejs 的代码:
<%if (user) {%>
Hello, <%= user.username %>!
<a href="/logout">Logout</a>
<%} else {%>
<form action="/login" method="post">
<input type="text" name="username" placeholder="Username" /><br/>
<input type="password" name="password" placeholder="Password" /><br/>
<button type="submit">Login</button>
</form>
<%}%>
下面是模板文件 home.ejs 的代码:
Hello, <%= user.username %>!
<a href="/logout">Logout</a>
3.2.4 测试
运行代码node app.js
后,在浏览器中访问http://localhost:3000
,可以看到如下页面。输入用户名和密码即可登录,登录成功后,进入home页面,显示当前用户的用户名和退出登录按钮,如图所示。
4. 总结
本文介绍了 Node.js 实现单点登录的基础知识、CAS 的工作流程、实现 CAS 的代码和模板结构,可以方便地在多个应用中实现单点登录。