一、什么是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

在这里插入图片描述

三、编写测试路由

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
//模拟登录
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 (对返回信息进行加密)

  • 配置插件
1
2
3
4
5
6
7
8
9
10
11
// app.js

const jwtKoa = require('koa-jwt')
app.use(jwtKoa(
{
secret:'1Hrj$_enferk' //密钥

}
).unless({
path:[/^\/users\/login/] //自定义哪些目录忽略 JWT 验证
}))

注:如果目录下使用 JWT 验证,每次访问该目录下的路由是需要携带 token 信息(即加密信息)才能访问该路由。

1
2
3
//对信息进行加密
const jwt = require('jsonwebtoken')
token = jwt.sign(userInfo, '1Hrj$_enferk',{expiresIn: '1h'})

在这里插入图片描述

五、服务端获取用户信息并解密信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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 是无法实现多进程之间的信息共享。