使用koa2实现后端JWT登录实战原理

175 阅读1分钟

使用koa2实现后端JWT登录实战原理

一、技术栈

koa2 + axios

二、实践流程

graph TD
登录接口生成token --> 绑定到接口返回值上 --> 前端登录成功保存token --> 前端调用接口将token带在header --> 后端使用koa-jwt生成中间件带入需要的接口/手写token验证

三、代码实现

  1. 登录接口生成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('登录异常')
	}
}
  1. 前端登录成功保存token:

由于方法较多,这里不讲前端内容,写一个最简单的演示:

API.login(userInfo).then(async (res) => {
	const { token } = res
	window.localStorage.setItem('token', token) // 缓存到localStorage
}) 
  1. 前端调用接口将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()
    }
  })
}

上述就是完整的验证原理和流程了,这些代码仅在实战项目中参考,并不能直接用哦,如哪里不清楚或者不当之处欢迎相互交流!