vue+egg+jwt实现登录验证的示例代码


Posted in Javascript onMay 18, 2019

原理:vue前端登录,提交账号密码给egg后端,后端比对信息后,使用jsonwebtoken对用户信息进行签名生成token,之后通过cookie返回给vue前端,前端需要使用token里的信息就使用js-base64进行token第二段解码即可。

vue前端路由跳转,进入路由前置守卫检测cookie中的token是否存在,不存在(已过期)则跳转登录,否则继续执行,然后在http拦截器里请求时存在token请求头带上token,后端未得到header则返回错误码,得到则用jsonwebtoken进行验证,是时间错误就从新发放token令牌,否则返回错误码,还要及时更新cookie时间,保证登录态.

vue前端main.js中:

import axios from 'axios';
import cookie from './public/util';
router.beforeEach((to, from, next) => {
 console.log('路由拦截')
 //判断要去的路由有没有requiresAuth
 if (to.meta.requiresAuth) {
  let token = cookie.getCookie('token');
  if (token) {
   next();
  } else {
   next({
    path: '/login'
   });
  }
 } else {
  next(); //如果无需token,那么随它去吧
 }
})
// http request 拦截器
axios.interceptors.request.use(
 config => {
  let token = cookie.getCookie('token');
  console.log(token)
  if (token) { // 判断是否存在token,如果存在的话,则每个http header都加上token
   config.headers.authorization = `token ${token}`;
  }
  return config;
 },
 err => {
  return Promise.reject(err);
 });
 
// http response 拦截器
axios.interceptors.response.use(
 response => {
  return response;
 },
 error => {
  if (error.response) {
   switch (error.response.status) {
    case 401:
     // 返回 401 清除token信息并跳转到登录页面
     router.replace({
      path: '/login'
     });
   }
  }
  return Promise.reject(error.response.data);  // 返回接口返回的错误信息
 });
Vue.prototype.$http = axios;

其中util.js中我封装了操作cookie的方法

//获取cookie、
function getCookie(name) {
  var arr, reg = new RegExp("(^| )" + name + "=([^;]*)(;|$)");
  if (arr = document.cookie.match(reg))
   return (arr[2]);
  else
   return null;
  }
  
  //设置cookie,增加到vue实例方便全局调用
function setCookie (c_name, value, expiredays) {
  var exdate = new Date();
  exdate.setDate(exdate.getDate() + expiredays);
  document.cookie = c_name + "=" + escape(value) + ((expiredays == null) ? "" : ";expires=" + exdate.toGMTString());
  };
  
  //删除cookie
function delCookie (name) {
  var exp = new Date();
  exp.setTime(exp.getTime() - 1);
  var cval = getCookie(name);
  if (cval != null)
   document.cookie = name + "=" + cval + ";expires=" + exp.toGMTString();
  };
  module.exports = {
  getCookie:getCookie,
  setCookie:setCookie,
  delCookie:delCookie
  }

路由中需要登录才能访问的页面,应:

path:'/admin/manager',component:Page,name:'管理系统首页',meta:{requiresAuth:true}

如果需要获取token中的信息则:

let token = cookie.getCookie('token');
let Base64 = require('js-base64').Base64;
let str = token.split('.')[1];
let user = JSON.parse(Base64.decode(str));
console.log(user)

后端在登录逻辑执行完后,需要给前端发放token

let jwt = require('jsonwebtoken');
    let token = jwt.sign({
      user_id:1,
      user_name: '张三'
     }, '自定义签名盐值', {
      expiresIn: '60s' //时间根据自己定,具体可参考jsonwebtoken插件官方说明
     });
this.ctx.cookies.set('token', token, {maxAge:60*1000,httpOnly:false,overwrite:true,signed:false})
this.ctx.body = true;

接着是中间件:

module.exports = () => {
 const jwt = require('jsonwebtoken');
 return async function (ctx, next) {
  if (ctx.request.header['authorization']) {
   let token = ctx.request.header['authorization'].split(' ')[1];
   console.log(token)
   let decoded;
   //解码token
   try {
    decoded = jwt.verify(token, '加签时定义的盐值');
   } catch (error) {
    if (error.name == 'TokenExpiredError') {
     console.log('时间到期')
     //重新发放令牌
     token = jwt.sign({
      user_id: 1,
      user_name: '张三'
     }, 'sinner77', {
      expiresIn: '60s' //过期时间设置为60妙。那么decode这个token的时候得到的过期时间为 : 创建token的时间 + 设置的值
     });
     ctx.cookies.set('token', token, {
      maxAge: 60 * 1000,
      httpOnly: false,
      overwrite: true,
      signed: false
     });
    } else {
     ctx.status = 401;
     ctx.body = {
      message: 'token失效'
     }
     return;
    }
   }
   //重置cookie时间
   ctx.cookies.set('token', token, {
    maxAge: 60 * 1000,
    httpOnly: false,
    overwrite: true,
    signed: false
   });
   await next();
  } else {
   ctx.status = 401;
   ctx.body = {
    message: '没有token'
   }
   return;
  }
 }
};

最后在需要登录才可访问的资源路由上使用该中间件,如:

const checktoken = app.middleware.checktoken();
 router.get('/test',checktoken,controller.util.test);

至此,以cookie维护登录态,token做登录权限验证就完成了

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
js设置function参数默认值(适合没有传参情况)
Feb 24 Javascript
优化RequireJS项目的相关技巧总结
Jul 01 Javascript
Bootstrap创建可折叠的组件
Feb 23 Javascript
微信小程序 WebSocket详解及应用
Jan 21 Javascript
Angular 4.x 路由快速入门学习
May 03 Javascript
JQuery 选择器、DOM节点操作练习实例
Sep 28 jQuery
浅谈Angular文字折叠展开组件的原理分析
Nov 24 Javascript
在vue中给列表中的奇数行添加class的实现方法
Sep 05 Javascript
微信小程序实现带缩略图轮播效果
Nov 04 Javascript
vue axios post发送复杂对象问题
Jun 04 Javascript
Node.js实现简单管理系统
Sep 23 Javascript
ES6之Proxy的get方法详解
Oct 11 Javascript
egg.js的基本使用和调用数据库的方法示例
May 18 #Javascript
inquirer.js一个用户与命令行交互的工具详解
May 18 #Javascript
webpack 代码分离优化快速指北
May 18 #Javascript
如何实现小程序tab栏下划线动画效果
May 18 #Javascript
微信小程序结合Storage实现搜索历史效果
May 18 #Javascript
Fetch超时设置与终止请求详解
May 18 #Javascript
微信小程序实现搜索历史功能
Mar 26 #Javascript
You might like
给海燕B411配件机起死回生配上件
2021/03/02 无线电
如何利用php+mysql保存和输出文件
2006/10/09 PHP
PHP调用三种数据库的方法(1)
2006/10/09 PHP
php 随机生成10位字符代码
2009/03/26 PHP
解析php中die(),exit(),return的区别
2013/06/20 PHP
WordPress中注册菜单与调用菜单的方法详解
2015/12/18 PHP
PHP区块查询实现方法分析
2018/05/12 PHP
php实现有序数组旋转后寻找最小值方法
2018/09/27 PHP
在laravel中使用with实现动态添加where条件
2019/10/10 PHP
贴一个在Mozilla中常用的Javascript代码
2007/01/09 Javascript
jQuery选择没有colspan属性的td的代码
2010/07/06 Javascript
extjs ColumnChart设置不同的颜色实现代码
2013/05/17 Javascript
js showModalDialog 弹出对话框的简单实例(子窗体)
2014/01/07 Javascript
jQuery实现鼠标经过图片预览大图效果
2014/04/10 Javascript
js实现分享到随页面滚动而滑动效果的方法
2015/04/10 Javascript
浅谈jquery中的each方法$.each、this.each、$.fn.each
2016/06/23 Javascript
ES6学习笔记之正则表达式和字符串正则方法分析
2017/04/25 Javascript
基于bootstrap页面渲染的问题解决方法
2018/08/09 Javascript
从零开始封装自己的自定义Vue组件
2018/10/09 Javascript
vue 使用vue-i18n做全局中英文切换的方法
2018/10/29 Javascript
checkbox在vue中的用法小结
2018/11/13 Javascript
python二叉树遍历的实现方法
2013/11/21 Python
Python的Tornado框架异步编程入门实例
2015/04/24 Python
Python中的fileinput模块的简单实用示例
2015/07/09 Python
从零开始学Python第八周:详解网络编程基础(socket)
2016/12/14 Python
keras 多gpu并行运行案例
2020/06/10 Python
基于Python实现2种反转链表方法代码实例
2020/07/06 Python
使用tkinter实现三子棋游戏
2021/02/25 Python
Mamas & Papas沙特阿拉伯:英国最受欢迎的婴儿品牌
2017/11/20 全球购物
香港中原电器网上商店:Chung Yuen
2019/06/26 全球购物
母亲节演讲稿范文
2014/01/02 职场文书
2014年最新党员对照检查材料汇总
2014/09/15 职场文书
组织生活会表态发言材料
2014/10/17 职场文书
2015年英语教研组工作总结
2015/05/23 职场文书
2015年法律事务部工作总结
2015/07/27 职场文书
python保存图片的四个常用方法
2022/02/28 Python