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 相关文章推荐
基于jQuery的前端数据通用验证库
Aug 08 Javascript
javascript实现的平方米、亩、公顷单位换算小程序
Aug 11 Javascript
angularjs中的单元测试实例
Dec 06 Javascript
JavaScript定时显示广告代码分享
Mar 02 Javascript
轻量级javascript 框架Backbone使用指南
Jul 24 Javascript
js实现带有介绍的Select列表菜单实例
Aug 18 Javascript
原生JS实现美图瀑布流布局赏析
Sep 07 Javascript
几种经典排序算法的JS实现方法
Mar 25 Javascript
js选择器全面解析
Jun 27 Javascript
js自定义弹框插件的封装
Aug 24 Javascript
vue实现点击关注后及时更新列表功能
Jun 26 Javascript
移动端手指操控左右滑动的菜单
Sep 08 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
56.com视频采集接口程序(PHP)
2007/09/22 PHP
php文章内容分页并生成相应的htm静态页面代码
2010/06/07 PHP
php设计模式 DAO(数据访问对象模式)
2011/06/26 PHP
php入门学习知识点二 PHP简单的分页过程与原理
2011/07/14 PHP
PHP实现图片裁剪、添加水印效果代码
2014/10/01 PHP
深入浅析PHP无限极分类的案例教程
2016/05/09 PHP
php使用 readfile() 函数设置文件大小大小的方法
2017/08/11 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
laravel框架使用阿里云短信发送消息操作示例
2020/02/15 PHP
Knockoutjs的环境搭建教程
2012/11/26 Javascript
node.js中的console.time方法使用说明
2014/12/09 Javascript
浅谈Javascript实现继承的方法
2015/07/06 Javascript
PHP获取当前页面完整URL的方法
2016/12/02 Javascript
bootstrap常用组件之头部导航实现代码
2017/04/20 Javascript
Vue.js 动态为img的src赋值方法
2018/03/14 Javascript
javaScript产生随机数的用法小结
2018/04/21 Javascript
官方推荐react-navigation的具体使用详解
2018/05/08 Javascript
JavaScript对象的浅拷贝与深拷贝实例分析
2018/07/25 Javascript
mpvue中使用flyjs全局拦截的实现代码
2018/09/13 Javascript
vue中的 $slot 获取插槽的节点实例
2019/11/12 Javascript
[50:28]2018DOTA2亚洲邀请赛 3.31 小组赛 A组 Newbee vs KG
2018/04/01 DOTA
[01:08:44]NB vs VP 2018国际邀请赛小组赛BO2 第一场 8.18
2018/08/19 DOTA
Python3多线程爬虫实例讲解代码
2018/01/05 Python
使用 Django Highcharts 实现数据可视化过程解析
2019/07/31 Python
python区分不同数据类型的方法
2019/10/14 Python
CSS3属性box-shadow使用指南
2014/12/09 HTML / CSS
简洁自适应404页面HTML好看的404源码
2020/12/16 HTML / CSS
viagogo英国票务平台:演唱会、体育比赛、戏剧门票
2017/03/24 全球购物
size?丹麦官网:英国伦敦的球鞋精品店
2019/04/15 全球购物
单身联谊活动方案
2014/01/29 职场文书
模范家庭事迹材料
2014/02/10 职场文书
2014年师德承诺书
2014/05/23 职场文书
网上祭先烈心得体会
2014/09/01 职场文书
2015年教师新年寄语
2014/12/08 职场文书
详解MySQL数据库千万级数据查询和存储
2021/05/18 MySQL
解决spring.thymeleaf.cache=false不起作用的问题
2022/06/10 Java/Android