详解vue项目中使用token的身份验证的简单实践


Posted in Javascript onMarch 08, 2019

工作原理

  • 前端页面进行登录操作, 将用户名与密码发给服务器;
  • 服务器进行效验, 通过后生成token, 包含信息有密钥, uid, 过期时间, 一些随机算法等 ,然后返回给前端
  • 前端将token保存在本地中, 建议使用localstorage进行保存.  下次对服务器发送请求时, 带上本地存储的token
  • 服务器端,进行对token的验证, 通过的话, 进行相应的增删改查操作, 并将数据返回给前端
  • 为通过则返回错误码, 提示保错信息, 然后跳转到登录页.

具体步骤

所用技术: vuex + axios + localStorage + vue-router

1、在登录路由添加自定义mate字段, 来记录该页面是否需要身份验证

//router.js
{
 path: "/index",
 name: "index",
 component: resolve => require(['./index.vue'], resolve),
 meta: { 
  requiresAuth: true 
 }
}

2、设置路由拦截

router.beforeEach((to, from, next) => {
 //matched的数组中包含$route对象的检查元字段
 //arr.some() 表示判断该数组是否有元素符合相应的条件, 返回布尔值
 if (to.matched.some(record => record.meta.requiresAuth)) {
  //判断当前是否有登录的权限
  if (!auth.loggedIn()) {
   next({
    path: '/login',
    query: { redirect: to.fullPath }
   })
  } else {
   next()
  }
 } else {
  next() // 确保一定要调用 next()
 }
})

3、设置拦截器

这里使用axios的拦截器,对所有请求进行拦截判断。

在后面的所有请求中都将携带token进行. 我们利用axios中的拦截器, 通过配置http response inteceptor, 当后端接口返回401 (未授权), 让用户重新执行登录操作。

// http request 拦截器
axios.interceptors.request.use(
 config => {
  if (store.state.token) { // 判断是否存在token,如果存在的话,则每个http header都加上token
   config.headers.Authorization = `token ${store.state.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信息并跳转到登录页面
     store.commit(types.LOGOUT);
     router.replace({
      path: 'login',
      query: {redirect: router.currentRoute.fullPath}
     })
   }
  }
  return Promise.reject(error.response.data) // 返回接口返回的错误信息
});

4、将token存储在本地中

可以使用cookies/local/sessionStograge

三者的区别:

  • sessionStorage 不能跨页面共享的,关闭窗口即被清除,
  • localStorage 可以同域共享,并且是持久化存储的
  • 在 local / session storage 的 tokens,就不能从不同的域名中读取,甚至是子域名也不行.
  • 解决办法使用Cookie.demo: 假设当用户通过 app.yourdomain.com 上面的验证时你生成一个 token 并且作为一个 cookie 保存到 .yourdomain.com,然后,在 youromdain.com 中你可以检查这个 cookie 是不是已经存在了,并且如果存在的话就转到 app.youromdain.com去。这个 token 将会对程序的子域名以及之后通常的流程都有效(直到这个 token 超过有效期)只是利用cookie的特性进行存储而非验证.

关于XSS和XSRF的防范:

  • XSS 攻击的原理是,攻击者插入一段可执行的 JavaScripts 脚本,该脚本会读出用户浏览器的 cookies 并将它传输给攻击者,攻击者得到用户的 Cookies 后,即可冒充用户。
  • 防范 XSS ,在写入 cookies 时,将 HttpOnly 设置为 true,客户端 JavaScripts 就无法读取该 cookies 的值,就可以有效防范 XSS 攻击。
  • CSRF是一种劫持受信任用户向服务器发送非预期请求的攻击方式。
  • 防范 CSRF: 因为 Tokens 也是储存在本地的 session storage 或者是客户端的 cookies 中,也是会受到 XSS 攻击。所以在使用 tokens 的时候,必须要考虑过期机制,不然攻击者就可以永久持有受害用户帐号。

相关文章: XSS 和 CSRF简述及预防措施

//login.vue
 methods: {
  login(){
   if (this.token) {
    //存储在本地的localStograge中
    this.$store.commit(types.LOGIN, this.token)
    //跳转至其他页面
    let redirect = decodeURIComponent(this.$route.query.redirect || '/');
    this.$router.push({
     path: redirect
    })
   }
  }
 }

在vuex中:

import Vuex from 'vuex';
import Vue from 'vue';
import * as types from './types'

Vue.use(Vuex);
export default new Vuex.Store({
 state: {
  user: {},
  token: null,
  title: ''
 },
 mutations: {
  //登录成功将, token保存在localStorage中
  [types.LOGIN]: (state, data) => {
   localStorage.token = data;
   state.token = data;
  },
  //退出登录将, token清空
  [types.LOGOUT]: (state) => {
   localStorage.removeItem('token');
   state.token = null
  }
 }
});

在./types.js中:

export const LOGIN = 'login';
export const LOGOUT = 'logout';

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript 变量命名规则
Sep 23 Javascript
javascript 跨浏览器开发经验总结(五) js 事件
May 19 Javascript
JavaScript高级程序设计(第3版)学习笔记9 js函数(下)
Oct 11 Javascript
正则表达式搭配js轻松处理json文本方便而老古
Feb 17 Javascript
jquery 选取方法都有哪些
May 18 Javascript
jQuery插件multiScroll实现全屏鼠标滚动切换页面特效
Apr 12 Javascript
jQuery实现Tab选项卡切换效果简单演示
Nov 23 Javascript
js实现图片轮播效果
Dec 19 Javascript
jQuery 获取遍历获取table中每一个tr中的第一个td的方法
Oct 05 Javascript
JQuery Ajax 异步操作之动态添加节点功能
May 24 jQuery
JavaScript 有用的代码片段和 trick
Feb 22 Javascript
vue中利用mqtt服务端实现即时通讯的步骤记录
Jul 01 Vue.js
Javascript之高级数组API的使用实例
Mar 08 #Javascript
详解基于vue-cli3快速发布一个fullpage组件
Mar 08 #Javascript
JavaScript实现预览本地上传图片功能完整示例
Mar 08 #Javascript
详解JavaScript 的变量
Mar 08 #Javascript
Angular使用ControlValueAccessor创建自定义表单控件
Mar 08 #Javascript
小程序测试后台服务的方法(ngrok)
Mar 08 #Javascript
详解JavaScript函数callee、call、apply的区别
Mar 08 #Javascript
You might like
PHP中$_SERVER的详细参数与说明
2008/07/29 PHP
php flv视频时间获取函数
2010/06/29 PHP
PHP的博客ping服务代码
2012/02/04 PHP
变量在 PHP7 内部的实现(二)
2015/12/21 PHP
遍历指定目录,并存储目录内所有文件属性信息的php代码
2016/10/28 PHP
PHP的mysqli_sqlstate()函数讲解
2019/01/23 PHP
解决 FireFox 下[使用event很麻烦] 的问题.
2006/08/22 Javascript
List the UTC Time on a Computer
2007/06/11 Javascript
JavaScript获取GridView中用户点击控件的行号,列号
2009/04/14 Javascript
Prototype Template对象 学习
2009/07/19 Javascript
检测jQuery.js是否已加载的判断代码
2011/05/20 Javascript
javascript suggest效果 自动完成实现代码分享
2012/02/17 Javascript
js对象关系图 方便dom操作
2012/03/18 Javascript
jQuery实现鼠标可拖动调整表格列宽度
2014/05/26 Javascript
浅谈javascript运算符——条件,逗号,赋值,()和void运算符
2016/07/15 Javascript
js实现点击每个li节点,都弹出其文本值及修改
2016/12/15 Javascript
Angular2里获取(input file)上传文件的内容的方法
2017/09/05 Javascript
基于百度地图api清除指定覆盖物(Overlay)的方法
2018/01/26 Javascript
vue2.0 computed 计算list循环后累加值的实例
2018/03/07 Javascript
vue移动端路由切换实例分析
2018/05/14 Javascript
vue修改对象的属性值后页面不重新渲染的实例
2018/08/09 Javascript
如何通过shell脚本自动生成vue文件详解
2019/09/10 Javascript
原生js+canvas实现下雪效果
2020/08/02 Javascript
[30:51]DOTA2上海特级锦标赛主赛事日 - 3 胜者组第二轮#1Liquid VS MVP.Phx第一局
2016/03/04 DOTA
Python语言描述机器学习之Logistic回归算法
2017/12/21 Python
python将字典内容存入mysql实例代码
2018/01/18 Python
解决python3 pika之连接断开的问题
2018/12/18 Python
pyqt5 使用cv2 显示图片,摄像头的实例
2019/06/27 Python
Python matplotlib生成图片背景透明的示例代码
2019/08/30 Python
Python re正则表达式元字符分组()用法分享
2020/02/10 Python
详解Python3中的 input() 函数
2020/03/18 Python
Python生成器常见问题及解决方案
2020/03/21 Python
Python HTTP下载文件并显示下载进度条功能的实现
2020/04/02 Python
django queryset相加和筛选教程
2020/05/18 Python
基于CSS3实现图片模糊过滤效果
2015/11/19 HTML / CSS
Python 文本滚动播放器的实现代码
2021/04/25 Python