vue-koa2-token
基于 vue 的 做了 token 验证
前端部分 (对 axios 设置 Authorization)
- import axios from 'axios'
- import store from '../store'
- import router from '../router'
- // 设置全局 axios 默认值
- axios.defaults.timeout = 6000; //6000 的超时验证
- axios.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
- // 创建一个 axios 实例
- const instance = axios.create();
- instance.defaults.headers.post['Content-Type'] = 'application/json;charset=UTF-8';
- axios.interceptors.request.use = instance.interceptors.request.use;
- //request 拦截器
- instance.interceptors.request.use(
- config => {
- // 每次发送请求之前检测都 vuex 存有 token, 那么都要放在请求头发送给服务器
- if(store.state.token){
- config.headers.Authorization = `token ${store.state.token}`;
- }
- return config;
- },
- err => {
- return Promise.reject(err);
- }
- );
- //respone 拦截器
- instance.interceptors.response.use(
- response => {
- return response;
- },
- error => { // 默认除了 2XX 之外的都是错误的, 就会走这里
- if(error.response){
- switch(error.response.status){
- case 401:
- store.dispatch('UserLogout'); // 可能是 token 过期, 清除它
- router.replace({ // 跳转到登录页面
- path: 'login',
- query: { redirect: router.currentRoute.fullPath } // 将跳转的路由 path 作为参数, 登录成功后跳转到该路由
- });
- }
- }
- return Promise.reject(error.response);
- }
- );
- export default instance;
然后在路由文件中
- // 注册全局钩子用来拦截导航
- router.beforeEach((to, from, next) => {
- // 获取 store 里面的 token
- let token = store.state.token;
- // 判断要去的路由有没有 requiresAuth
- if(to.meta.requiresAuth){
- if(token){
- next();
- }else{
- next({
- path: '/login',
- query: { redirect: to.fullPath } // 将刚刚要去的路由 path(却无权限) 作为参数, 方便登录成功后直接跳转到该路由
- });
- }
- }else{
- next();// 如果无需 token, 那么随它去吧
- }
- });
后端 (node) 我们封装了一个中间件 在需要验证 token 的路由, 加上这个中间件
- router.get('/dosh',checkToken,User.dosh)
- const jwt = require('jsonwebtoken');
1, 使用 jsonwebtoken 创建 token
- const jwt = require('jsonwebtoken');
- // 登录时: 核对用户名和密码成功后, 应用将用户的 id(图中的 user_id) 作为 JWT Payload 的一个属性
- module.exports = function(user_id){
- const token = jwt.sign({
- user_id: user_id
- }, 'sinner77', {
- expiresIn: '3600s' // 过期时间设置为 60 妙. 那么 decode 这个 token 的时候得到的过期时间为 : 创建 token 的时间 + 设置的值
- });
- return token;
- };
2, 对于前端的请求, 校验接口
- // 检查 token 是否过期
- module.exports = async ( ctx, next ) => {
- if(ctx.request.header['authorization']){
- let token = ctx.request.header['authorization'].split(' ')[1];
- // 解码 token
- let decoded = jwt.decode(token, 'sinner77');
- //console.log(decoded); 的输出 :{ user_id: '123123123', iat: 1494405235, exp: 1494405235 }
- if(token && decoded.exp <= new Date()/1000){
- ctx.status = 401;
- ctx.body = {
- message: 'token 过期'
- };
- }else{
- // 如果权限没问题, 那么交个下一个控制器处理
- return next();
- }
- }else{
- ctx.status = 401;
- ctx.body = {
- message: '没有 token'
- }
- }
- };
来源: http://www.qdfuns.com/article/20013/3dad0fee3f8f4f02e286f22731243cc3.html