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 相关文章推荐
给超链接添加特效鼠标移动展示提示信息且随鼠标移动
Oct 17 Javascript
js点击选择文本的方法
Feb 09 Javascript
JavaScript中setUTCMilliseconds()方法的使用详解
Jun 12 Javascript
jQuery实现鼠标经过时出现隐藏层文字链接的方法
Oct 12 Javascript
简介BootStrap model弹出框的使用
Apr 27 Javascript
javascript遍历json对象的key和任意js对象属性实例
Mar 09 Javascript
jQuery 1.9版本以上的浏览器判断方法代码分享
Aug 28 jQuery
动手写一个angular版本的Message组件的方法
Dec 16 Javascript
vue图片上传本地预览组件使用详解
Feb 20 Javascript
Vue表单之v-model绑定下拉列表功能
May 14 Javascript
Javascript通过控制类名更改样式
May 24 Javascript
js get和post请求实现代码解析
Feb 06 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
PHP自动生成月历代码
2006/10/09 PHP
如何在PHP中使用Oracle数据库(5)
2006/10/09 PHP
php判断文件上传类型及过滤不安全数据的方法
2014/12/17 PHP
PHP中使用register_shutdown_function函数截获fatal error示例
2015/04/21 PHP
PHP实现的回溯算法示例
2017/08/15 PHP
javascript div 遮罩层封锁整个页面
2009/07/10 Javascript
js中eval()函数和trim()去掉字符串左右空格应用
2013/02/02 Javascript
jQuery 回车事件enter使用示例
2014/02/18 Javascript
JQuery悬停控制图片轮播——代码简单
2015/08/05 Javascript
javascript学习笔记整理(概述、变量、数据类型简介)
2015/10/25 Javascript
使用微信内置浏览器点击下拉框出现页面乱跳转现象(iphone),该怎么办
2016/01/04 Javascript
使用基于Node.js的构建工具Grunt来发布ASP.NET MVC项目
2016/02/15 Javascript
深入解析JavaScript中函数的Currying柯里化
2016/03/19 Javascript
浅述节点的创建及常见功能的实现
2016/12/15 Javascript
JS中touchstart事件与click事件冲突的解决方法
2018/03/12 Javascript
Vue实现根据hash高亮选项卡
2019/05/27 Javascript
ES6之Proxy的get方法详解
2019/10/11 Javascript
12 种使用Vue 的最佳做法
2020/03/30 Javascript
vue scroll滚动判断的实现(是否滚动到底部、滚动方向、滚动节流、获取滚动区域dom元素)
2020/06/11 Javascript
Python中getattr函数和hasattr函数作用详解
2016/06/14 Python
用Python将动态GIF图片倒放播放的方法
2016/11/02 Python
Python中实现变量赋值传递时的引用和拷贝方法
2018/04/29 Python
《与孩子一起学编程》python自测题
2018/05/27 Python
简单了解python中对象的取反运算符
2019/07/01 Python
python多线程实现同时执行两个while循环的操作
2020/05/02 Python
详解CSS3 弹性布局快速入门
2019/06/06 HTML / CSS
用React加CSS3实现微信拆红包动画效果
2017/03/13 HTML / CSS
Oroton中国官网:澳洲知名奢侈配饰品牌
2017/03/26 全球购物
捷克家电和家具购物网站:OKAY.cz
2020/07/23 全球购物
琳达·法罗眼镜英国官网:Linda Farrow英国
2021/01/19 全球购物
新店开张活动方案
2014/08/24 职场文书
违反交通法规检讨书
2014/09/10 职场文书
2015年检验科工作总结
2015/04/27 职场文书
新年祝酒词大全
2015/08/11 职场文书
用 Python 元类的特性实现 ORM 框架
2021/05/19 Python
Python尝试实现蒙特卡罗模拟期权定价
2022/04/21 Python