一、什么是JWT
- JWT —— json web token
- 用户认证成功之后,server 端返回一个加密的token给客户端
- 客户端后续每次请求都带 token ,以示当前的用户身份
二、搭建环境(koa2 环境)
npm install koa-generator -g
koa2 -e koa2-jwt-code
cd koa2-jwt-code
npm install
三、编写测试路由
//模拟登录
router.prefix('/users')
router.post('/login', async (ctx, next) => {
const { username, password } = ctx.request.body
let userInfo
if (username === 'zhangsan' && password === '123') {
userInfo = {
userId: 1,
userName: 'zhangsan',
password: '123',
nickName: '张三'
}
}
if (userInfo == null) {
ctx.body ={
errno: -1,
msg:"登录失败"
}
return
}
ctx.body = {
errno: 0,
userInfo
}
})
四、对返回的用户信息进行加密
- 安装插件
npm i koa-jwt --save (对是否为当前用户进行验证)
npm i jsonwebtoken --save (对返回信息进行加密)
- 配置插件
// app.js
const jwtKoa = require('koa-jwt')
app.use(jwtKoa(
{
secret:'1Hrj$_enferk' //密钥
}
).unless({
path:[/^\/users\/login/] //自定义哪些目录忽略 JWT 验证
}))
注:如果目录下使用 JWT 验证,每次访问该目录下的路由是需要携带 token 信息(即加密信息)才能访问该路由。
//对信息进行加密
const jwt = require('jsonwebtoken')
token = jwt.sign(userInfo, '1Hrj$_enferk',{expiresIn: '1h'})
五、服务端获取用户信息并解密信息
const until = require('util')
const verify = until.promisify(jwt.verify)
router.get('/getUserInfo', async (ctx, next) => {
const token = ctx.header.authorization
try {
const payload = await verify(token.split(' ')[1], '1Hrj$_enferk')
ctx.body = {
errno:0,
userInfo: payload
}
} catch (ex) {
ctx.body = {
errno:-1,
msg:'失败'
}
}
})
六、JWT vs Session
共同点:为了解决:登录和存储登录用户信息
不同点:
- JWT 用户信息加密存储在客户端,不依赖 cookie ,可跨域。
- session 用户信息存储在服务端,依赖于 cookie,默认不可跨域 。
JWT 的优点:
- 将加密信息存放在客户端,减少服务端的内存压力。
- 不依赖于 cookie 可以将信息进行跨域分享。
JWT的不足:
- 服务端无法控制信息,一旦用户修改信息后,服务端无法第一时间修改加密信息。
Session的优点:
- 可以对用户信息进行控制。
Session的不足:
- 存储要依赖于 redis 和 cookie ,并且不能跨域。
- 一旦上线启动多进程,而不依赖 redis 是无法实现多进程之间的信息共享。