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 相关文章推荐
struts2 jquery 打造无限层次的树
Oct 23 Javascript
javascript实现的在当前窗口中漂浮框的代码
Mar 15 Javascript
javascript游戏开发之《三国志曹操传》零部件开发(四)用地图块拼成大地图
Jan 23 Javascript
针对JavaScript中this指向的简单理解
Aug 26 Javascript
Angular ng-repeat 对象和数组遍历实例
Sep 14 Javascript
微信公众号 摇一摇周边功能开发
Dec 08 Javascript
JS重载实现方法分析
Dec 16 Javascript
vue中实现滚动加载更多的示例
Nov 08 Javascript
如何用Node写页面爬虫的工具集
Oct 26 Javascript
JS删除String里某个字符的方法
Jan 06 Javascript
详解django模板与vue.js冲突问题
Jul 07 Javascript
使用Vue实现简单计算器
Feb 25 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 遍历数据表数据并列表横向排列的代码
2009/09/05 PHP
PHP如何解决网站大流量与高并发的问题
2011/06/25 PHP
header中Content-Disposition的作用与使用方法
2012/06/13 PHP
浅谈php函数serialize()与unserialize()的使用方法
2014/08/19 PHP
Codeigniter发送邮件的方法
2015/03/19 PHP
PHP中数据类型转换的三种方式
2015/04/02 PHP
详解WordPress开发中的get_post与get_posts函数使用
2016/01/04 PHP
php判断是否连接上网络的方法实例详解
2016/12/14 PHP
Laravel框架中自定义模板指令总结
2017/12/17 PHP
thinkPHP+mysql+ajax实现的仿百度一下即时搜索效果详解
2019/07/15 PHP
一步一步制作jquery插件Tabs实现过程
2010/07/06 Javascript
jquery实现点击查看更多内容控制段落文字展开折叠效果
2015/08/06 Javascript
window.location.hash知识汇总
2015/11/09 Javascript
温故知新——JavaScript中的字符串连接问题最全总结(推荐)
2017/08/21 Javascript
JavaScript事件处理程序详解
2017/09/19 Javascript
详解如何构建Promise队列实现异步函数顺序执行
2018/10/23 Javascript
加快Vue项目的开发速度的方法
2018/12/12 Javascript
js实现简单音乐播放器
2020/06/30 Javascript
vue路由切换时取消之前的所有请求操作
2020/09/01 Javascript
[51:29]Alliance vs TNC 2019国际邀请赛小组赛 BO2 第二场 8.16
2019/08/18 DOTA
python之模拟鼠标键盘动作具体实现
2013/12/30 Python
Python的Django框架安装全攻略
2015/07/15 Python
深入剖析Python的爬虫框架Scrapy的结构与运作流程
2016/01/20 Python
Python简单实现enum功能的方法
2016/04/25 Python
python 寻找优化使成本函数最小的最优解的方法
2017/12/28 Python
简单实现python收发邮件功能
2018/01/05 Python
face++与python实现人脸识别签到(考勤)功能
2019/08/28 Python
Python enumerate内置库用法解析
2020/02/24 Python
解决阿里云邮件发送不能使用25端口问题
2020/08/07 Python
详解pandas赋值失败问题解决
2020/11/29 Python
剪枝的学问教学反思
2014/02/07 职场文书
副职竞争上岗演讲稿
2014/05/12 职场文书
趵突泉导游词
2015/02/03 职场文书
合同审查法律意见书
2015/06/04 职场文书
springboot+zookeeper实现分布式锁
2022/03/21 Java/Android
详细介绍python操作RabbitMq
2022/04/12 Python