使用koa2实现后端JWT登录实战原理
一、技术栈
koa2 + axios
二、实践流程
graph TD
登录接口生成token --> 绑定到接口返回值上 --> 前端登录成功保存token --> 前端调用接口将token带在header --> 后端使用koa-jwt生成中间件带入需要的接口/手写token验证
三、代码实现
- 登录接口生成token、绑定返回值
// 这里用最简化版本的登录接口实现 默认koa2内
const jwt = require('jsonwebtoken')
async Login(ctx) {
const { userName, userPassword } = ctx.request.body
// 这里说明一下,因为我用的MongoDB,这里User是用户的schema,这里查找的是当前登录用户数据
const data = await User.findOne({ userName, userPassword })
if (data) {
// 第一个参数表示载体,第二个参数加密字符串,第三个参数过期时间
const token = jwt.sign({ data }, 'secret', { expiresIn: 1d }) // 生成token
data.token = token // 绑定返回值
ctx.body = data
} else {
ctx.body = new throw('登录异常')
}
}
- 前端登录成功保存token:
由于方法较多,这里不讲前端内容,写一个最简单的演示:
API.login(userInfo).then(async (res) => {
const { token } = res
window.localStorage.setItem('token', token) // 缓存到localStorage
})
- 前端调用接口将token带在header:
用axios演示吧:
// 一般项目都会二次封装axios吧...
const axios = require('axios')
const service = axios.create({
baseURL: '/api',
timeout: 10000
})
// 在所有请求接口上进行拦截并添加token到请求头
service.interceptors.request.use((req) => {
const headers = req.headers
const token = window.localStorage.getItem('token')
headers.Authorization = 'Bearea ' + token
return req
})
4.后端使用koa-jwt生成中间件带入需要的接口/手写token验证
// 直接使用koa-jwt验证
const jwt = require('koa-jwt')
const auth = jwt({secret: 'secret'})
router.get('/hello', auth, (ctx) => {
ctx.body = 'hello world'
})
// 手写token验证 中间件,当然这是简化版本
const jwt = require('jsonwebtoken')
const verifyToken = async (ctx, next) => {
const token = ctx.request.header.authorization.split(' ')[1]
const decoded = jwt.verify(token, 'secret', async (err, decode) => {
if (err) {
if (err.name == 'TokenExpiredError') {
ctx.body = 'token 已过期'
} else if (err.name == 'JsonWebTokenError') {
ctx.body = 'token 无效'
}
} else {
await next()
}
})
}
上述就是完整的验证原理和流程了,这些代码仅在实战项目中参考,并不能直接用哦,如哪里不清楚或者不当之处欢迎相互交流!