首先安装jsonwebtoken
npm install jsonwebtoken --save
【服务端】在koa2中新建一个token.js作为token验证的中间键
// token.js
const jwt = require('jsonwebtoken')
const verifyToken = async (ctx, next)=> {
let url = ctx.request.url.split('?')[0]
// 以下接口不校验token
let url_config = [
'/api/login',
'/api/register'
]
// 检测接口是否在不校验接口列表中
let changer = url_config.some((item) => {
return item == url
})
if (changer) {
// 不检测token
await next()
} else {
// 检测token
let token = ctx.request.headers["authorization"]
let userid = ctx.request.headers["userid"]
if (token && userid) {
let payload = jwt.verify(token, 'test', async (err, decode)=> {
if (err) {
if (err.name == 'TokenExpiredError') {
ctx.body = {
code: decode,
msg: 'token已过期'
}
} else if (err.name == 'JsonWebTokenError') {
ctx.body = {
code: decode,
msg: '无效的token'
}
}
} else {
if(payload.userid != userid) {
ctx.body = {
code: decode,
msg: '无效的token'
}
} else {
await next()
}
}
})
} else {
ctx.body = {
code: 1000,
msg: '登录信息已过期'
}
}
}
}
module.exports = verifyToken
然后再koa2入口文件中使用
const koa = require('koa')
const app = new koa()
// 自定义中间键
const verifyToken = require('./middleware/token.js') // token验证
app.use(verifyToken) // token验证
// 启动服务
let port = process.env.PORT || 3005
app.listen(port, () => {
console.log(`server runing at ${port}...`)
})
【前端】前端封装好axios,自己用ajax也可以,简单做一下二次封装就行了,主要是在headers里带上用户token与userid,我用的是vue3和element,所以直接在vue项目的main.js将方法全局挂载了
import { ElMessage } from "element-plus";
import $router from "../router/index.js";
const $ajax = (url, data) {
let token = "";
let userid = "";
if (localStorage.getItem("userInfo")) {
token = localStorage.getItem("userInfo").token;
userid = localStorage.getItem("userInfo").userid;
}
const instance = axios.create({
baseURL: "/api",
timeout: 8000,
crossDomain: true,
withCredentials: true,
headers: {
"Content-Type": "application/x-www-form-urlencoded",
"Assess-Control-Allow-Origin": "*",
from: "window",
authorization: token,
userid: userid,
},
});
// 响应拦截
instance.interceptors.response.use(
(response) => {
if (response.data.code == 0) {
// 接口正常
return response.data;
} else {
if (response.data.code == 10000) {
// 登录失效
$router.replace("/login");
}
ElMessage.error(response.data.msg);
return Promise.reject(response.data.msg);
}
},
(err) => {
return Promise.reject(err);
}
);
return new Promise((resolve, reject) => {
let request_url = $server[url];
if (data.method == "post") {
instance
.post(request_url, data)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
} else {
instance
.get(request_url, { params: data })
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
}
});
}
export default $ajax;
在main.js中全局挂载
import { createApp } from "vue";
import App from "./App.vue";
import router from "./router";
import store from "./store";
import $ajax from "./utils/ajax.js";
import ElementPlus from "element-plus";
import "element-plus/dist/index.css";
const app = createApp(App);
app.config.globalProperties.$ajax= $ajax; // 全局挂载
app.use(ElementPlus); // 使用element-ui
app.use(store).use(router).mount("#app");
使用示例
<template>
</template>
<script>
export default {
name: "Home",
data() {
return {}
},
onload() {
this.getList()
},
methods: {
getList() {
this.$ajax('api/getList').then(res=> {
// do something...
})
}
}
};
</script>