什么是JSON Web Token:
跨域认证解决方案,特别适用于分布式站点的单点登录(SSO)场景。
为什么要用Json Web Token?
我们知道HTTP通信是无状态的,因此客户端的请求到了服务端处理完之后是无法返回给原来的客户端。因此需要对访问的客户端进行识别,常用的做法是通过session机制:客户端在服务端登陆成功之后,服务端会生成一个sessionID,返回给客户端,客户端将sessionID保存到cookie中,再次发起请求的时候,携带cookie中的sessionID到服务端,服务端会缓存该session(会话),当客户端请求到来的时候,服务端就知道是哪个用户的请求,并将处理的结果返回给客户端,完成通信。
互联网服务离不开用户认证。一般流程是下面这样。
登录
① 用户登录时,将用户名和密码通过 POST 提交到服务端
② 服务端接收到登录数据之后,与数据库中的用户信息进行校验
③ 校验通过
④ 服务端通过用户 _id,secret 等等相关数据生成 JWT 字符串
⑤ 将 JWT 字符串和其他信息一起返回给浏览器,浏览器拿到 jwt 字符串后,缓存到本地,等待下一次请求
下一次请求
① 用户登录之后的每次请求,都会将 token 携带在请求头的 Authorization 中
② 对 token 验证成功之后,我们可以拿到保存在 token 中的用户数据
③ 进入业务处理
jwt 在 express 中的使用方法
安装依赖
jsonwebtoken: JSON Web Token 的具体实现,提供了一些和签名相关的常用方法。
npm install jsonwebtoken
**express-jwt:**用来验证 JsonWebTokens 和设置 req.user 的中间件,该模块允许我们在 express
中使用 jwt 验证 HTTP 请求。
npm install express-jwt
crypto:用于对数据进行加密。
npm install crypto
用法
用户登录成功之后,产生 token:
const jwt = require("jsonwebtoken");
router.post('/login', function (req, res, next) {
const payload = {
username: req.body.username,
};
let token = jwt.sign(
payload,
secretKey,
{
expiresIn: 60 * 60 // 秒
}
);
res.send({
success: true,
message: 'success',
token
});
});
客户端保存 token
在接下来的请求中,将 token 信息保存在请求头的 Authorization 中:
$.ajaxSettings.beforeSend = function (xhr, request) {
const user_token = window.localStorage.getItem('user_token');
xhr.setRequestHeader('Authorization', `Bearer ${user_token}`);
}
服务端校验 token
const expressJwt = require("express-jwt");
const { secretKey } = require('../utils/salt');
const jwtAuth = expressJwt({
secret: secretKey,
credentialsRequired: true // false:不校验
}).unless({
path: ["/users/login", "/users/reg"]
});
module.exports = jwtAuth;
express-jwt:用来校验每次请求中的 token 是否有效。 unless 配置哪些路径不需要校验。
工具类
我提供了一个工具类用来加密用户密码:
const crypto = require('crypto');
module.exports = {
MD5_SUFFIX: 'tangzhenhua_salt',
md5: (pwd) => {
let md5 = crypto.createHash('md5');
return md5.update(pwd).digest('hex');
},
secretKey: 'tangzhenhua_key'
};
好啦,下一章咱讲什么是单页应用,director.js 是什么