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 相关文章推荐
javascript 获取所有id中包含某关键字的控件的实现代码
Nov 25 Javascript
firefox浏览器不支持innerText的解决方法
Aug 07 Javascript
javascript设计简单的秒表计时器
Sep 05 Javascript
JavaScript实现瀑布流以及加载效果
Feb 11 Javascript
canvas实现简易的圆环进度条效果
Feb 28 Javascript
jquery 手势密码插件
Mar 17 Javascript
解决vue-quill-editor上传内容由于图片是base64的导致字符太长的问题
Aug 20 Javascript
vue如何获取自定义元素属性参数值的方法
May 14 Javascript
使用Vue.js中的过滤器实现幂方求值的方法
Aug 27 Javascript
关于JavaScript数组去重的一些理解汇总
Sep 10 Javascript
浅析微信小程序自定义日历组件及flex布局最后一行对齐问题
Oct 29 Javascript
Vue实现省市区三级联动
Dec 27 Vue.js
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
人大复印资料处理程序_查询篇
2006/10/09 PHP
PHP 加密/解密函数 dencrypt(动态密文,带压缩功能,支持中文)
2009/01/30 PHP
PHP运行出现Notice : Use of undefined constant 的完美解决方案分享
2012/03/05 PHP
php中simplexml_load_file函数用法实例
2014/11/12 PHP
PHP 二维关联数组根据其中一个字段排序(推荐)
2017/04/04 PHP
php弹出提示框的是实例写法
2019/09/26 PHP
Laravel框架Eloquent ORM简介、模型建立及查询数据操作详解
2019/12/04 PHP
通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法
2020/04/02 PHP
jquery load()在firefox(火狐)下显示不正常的解决方法
2011/04/05 Javascript
让JavaScript的Alert弹出框失效的方法禁止弹出警告框
2014/09/03 Javascript
javascript快速排序算法详解
2014/09/17 Javascript
JavaScript把数组作为堆栈使用的方法
2015/03/20 Javascript
json对象与数组以及转换成js对象的简单实现方法
2016/06/24 Javascript
JavaScript导航脚本判断当前导航
2016/07/12 Javascript
JS继承之借用构造函数继承和组合继承
2016/09/07 Javascript
利用Decorator如何控制Koa路由详解
2018/06/26 Javascript
Vue 开发必须知道的36个技巧(小结)
2019/10/09 Javascript
jQuery实现可以扩展的日历
2020/12/01 jQuery
[00:57]英雄,你的补给到了!
2020/11/13 DOTA
Python时间戳与时间字符串互相转换实例代码
2013/11/28 Python
Pthon批量处理将pdb文件生成dssp文件
2015/06/21 Python
使用Python多线程爬虫爬取电影天堂资源
2016/09/23 Python
让代码变得更易维护的7个Python库
2018/10/09 Python
为什么你还不懂得怎么使用Python协程
2019/05/13 Python
谈一谈数组拼接tf.concat()和np.concatenate()的区别
2020/02/07 Python
Python 实现将numpy中的nan和inf,nan替换成对应的均值
2020/06/08 Python
浅析Python 字符编码与文件处理
2020/09/24 Python
python遍历路径破解表单的示例
2020/11/21 Python
使用javascript和HTML5 Canvas画的四渐变色播放按钮效果
2014/04/10 HTML / CSS
Lacoste澳大利亚官网:服装、鞋类及配饰
2018/11/14 全球购物
英语专业推荐信
2013/11/16 职场文书
大学校运会广播稿
2014/02/03 职场文书
经济类毕业生求职信
2014/06/26 职场文书
人事任命通知书
2015/04/21 职场文书
篮球赛闭幕式主持词
2015/07/03 职场文书
晚会开幕词范文
2016/03/04 职场文书