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实现图片翻书效果示例代码
Sep 09 Javascript
javascript 按键事件(兼容各浏览器)
Dec 20 Javascript
js继承call()和apply()方法总结
Dec 08 Javascript
JS实现仿Windows7风格的网页右键菜单效果代码
Sep 11 Javascript
AngularJS实现textarea记录只能输入规定数量的字符并显示
Apr 26 Javascript
js 转义字符及URI编码详解
Feb 28 Javascript
vue router下的html5 history在iis服务器上的设置方法
Oct 18 Javascript
详解webpack require.ensure与require AMD的区别
Dec 13 Javascript
axios中cookie跨域及相关配置示例详解
Dec 20 Javascript
vue项目tween方法实现返回顶部的示例代码
Mar 02 Javascript
vue左右侧联动滚动的实现代码
Jun 06 Javascript
JS数组及对象遍历方法代码汇总
Jun 16 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
基于mysql的bbs设计(五)
2006/10/09 PHP
超小PHP小马小结(方便查找后门的朋友)
2012/05/05 PHP
PHP 获取客户端 IP 地址的方法实例代码
2018/11/11 PHP
encode脚本和normal脚本混用的问题与解决方法
2007/03/08 Javascript
jquery ui resizable bug解决方法
2010/10/26 Javascript
javascript禁用键盘功能键让右击及其他键无效
2013/10/09 Javascript
深入分析原生JavaScript事件
2014/12/29 Javascript
JavaScript获取网页中第一个图片id的方法
2015/04/03 Javascript
jquery实现界面无刷新加载登陆注册
2016/07/30 Javascript
js 提交form表单和设置form表单请求路径的实现方法
2016/10/25 Javascript
基于JavaScript实现自定义滚动条
2017/01/25 Javascript
Vue.js路由vue-router使用方法详解
2017/03/20 Javascript
Vuejs入门教程之Vue生命周期,数据,手动挂载,指令,过滤器
2017/04/19 Javascript
基于JavaScript实现报警器提示音效果
2017/10/27 Javascript
使用javascript做在线算法编程
2018/05/25 Javascript
从零开始在NPM上发布一个Vue组件的方法步骤
2018/12/20 Javascript
微信小程序使用canvas的画图操作示例
2019/01/18 Javascript
ES6中的迭代器、Generator函数及Generator函数的异步操作方法
2019/05/12 Javascript
[01:33]DOTA2上海特级锦标赛 LIQUID战队完整宣传片
2016/03/16 DOTA
Python的一些用法分享
2012/10/07 Python
python运行时间的几种方法
2016/06/17 Python
老生常谈Python序列化和反序列化
2017/06/28 Python
Django使用Celery异步任务队列的使用
2018/03/13 Python
Django使用AJAX调用自己写的API接口的方法
2019/03/06 Python
记录Python脚本的运行日志的方法
2019/06/05 Python
python安装virtualenv虚拟环境步骤图文详解
2019/09/18 Python
Python缓存技术实现过程详解
2019/09/25 Python
python3注册全局热键的实现
2020/03/22 Python
Pandas中DataFrame交换列顺序的方法实现
2020/12/14 Python
Smashbox英国官网:美国知名彩妆品牌
2017/11/13 全球购物
美国LOGO设计公司:The Logo Company
2018/07/16 全球购物
澳洲本土太阳镜品牌:Quay Australia
2019/07/29 全球购物
以思科路由器为例你写下单臂路由的配置命令
2013/08/03 面试题
2015年安全员工作总结范文
2015/04/22 职场文书
2015年医药代表工作总结
2015/04/25 职场文书
学历证明样本
2015/06/16 职场文书