加载中...

解析如何在vue前端处理token


解析如何在vue前端处理token

[toc]

token(令牌)是用户登录后获取的一种凭证。

那么,用户登录后访问其他API都需要携带token,才可以成功请求;所以如果没有携带,便不可以请求成功。

好处:如果不使用token,可能请求时都需要去验证用户名和密码,那么这就造成对服务器算力的浪费,使用token,便可以减少服务器的压力,减少频繁的查询数据库。

token具有时效性,可能有效期是几分钟,或者几天。

token生成机制一般是通过加密算法和盐把类似(用户名 + 时间戳 + 盐)生成串

而后端生成token后,会把它存在Redis(缓存)中。

使用token这项技术,后端可以做单点登录(只允许一个账号同时登录1次,不允许一个账号同时登录多次,是指在多系统应用群中登录一个系统,便可在其他所有系统中得到授权而无需再次登录,包括单点登录与单点注销两部分)

所以我们依然以《电商管理系统》这个项目为基础,分析

1、如何在登录之后存储token(登录的post请求,会返回一个token)

2、如何在访问其他API时,携带token(如何配置)

1、如何在登录之后存储token

需要在客户端存储token,

(1)可以存储在cookie中,

cookie指的就是浏览器里面能永久存储数据的一种数据存储功能。cookie由服务器生成,发送给浏览器,浏览器把cookie以kv形式保存到某个目录下的文本文件内,下一次请求同一网站时会把该cookie发送给服务器。

由于cookie是存在客户端上的,所以浏览器加入了一些限制确保cookie不会被恶意使用,同时不会占据太多磁盘空间,所以每个域的cookie数量是有限的。

(2)可以存储在sessionStorage或者是localStorage

cookie数据始终在同源的http请求中携带(即使不需要),即cookie在浏览器和服务器间来回传递,

localStorage 和 sessionStorage 属性允许在浏览器中存储 key/value 对的数据。

localStorage 用于长久保存整个网站的数据,保存的数据没有过期时间,直到手动去删除。

localStorage 属性是只读的。

如果你只想将数据保存在当前会话中,可以使用sessionStorage 属性, 该数据对象临时保存同一窗口(或标签页)的数据,在关闭窗口或标签页之后将会删除这些数据。

在js中,使用window对象调用sessionStorage和localStorage

Window 对象表示浏览器中打开的窗口。

此处补充一些window对象的内容:

(1)Window 对象的属性

closed 返回窗口是否已被关闭。
localStorage 在浏览器中存储 key/value 对。没有过期时间。
parent 返回父窗口
sessionStorage 在浏览器中存储 key/value 对。 在关闭窗口或标签页之后将会删除这些数据。

(2)Window 对象的方法

alert() 显示带有一段消息和一个确认按钮的警告框
clearTimeout() 取消由 setTimeout() 方法设置的 timeout
close() 关闭浏览器窗口
print() 打印当前窗口的内容。
setTimeout() 在指定的毫秒数后调用函数或计算表达式。

在登录页面中,在发起请求登录时,存储token代码如下:

login() {
  this.$refs.loginFormRef.validate(async valid => {
    // console.log(valid);
    if (!valid) return;
    const { data: res } = await this.$axios.post('login', this.loginForm);
    console.log(res);
    if (res.meta.status != 200) return this.$message.error('登录失败!');
    this.$message.success('登录成功!');
    // 1.将登录成功后的token,保存到客户端的sessionStorage中
    //    1.1项目中除了登录之外的其他API接口,必须在登录之后才能访问
    //    1.2token只应在当前网站打开期间生效,所以将token保存在sessionStorage中
    window.sessionStorage.setItem('token', res.data.token);
    // 2.通过编程式导航跳转到后台主页,路由地址是 /home
    this.$router.push('/home');
  });
}

可以通过浏览器在Application查看如下:

xiaomin

xiaomin

下面考虑第二个问题,

2、如何在访问其他API时,携带token(如何配置)

第一步:如果我们没有登录,直接通过URL,访问除了登录页面以外的页面,是不可以访问的,可以让它跳转到登录页面。这一步,我们利用路由导航守卫来完成

为router路由对象,添加beforeEach导航守卫。如果用户访问的是登录页,直接放行;如果访问是其他页面,则从sessionStorage取token,看是否为空,如果为空,则跳转到登录页。

router.beforeEach((to, from, next) => {
  //to将要访问的路径
  //from代表从哪个路径跳转而来
  //next是一个函数,表示放行
  //next() 放行 next('/login')强制跳转
  if (to.path === '/login') return next();
  //获取token
  const tokenStr = window.sessionStorage.getItem('token');
  if (!tokenStr) return next('/login');
  next();
});

注意next函数

  1. next() 放行

  2. next(‘/login’)跳转到指定页面

第二步:通过axios请求拦截器添加token

在接口文档中已经说明,需要授权的 API ,必须在请求头中使用 Authorization 字段提供 token 令牌 。

在导入axios包后,

做一个请求拦截器,类似于对请求进行预处理,我们在axios的一个use方法中,调用了一个箭头函数,这个箭头函数会将对请求头的Authorization字段填入token值

config即是一个请求对象

代码是在main.js入口文件中,配置如下:

axios.interceptors.request.use(config => {
  console.log(config);
  config.headers.Authorization = window.sessionStorage.getItem('token');
  // 在最后必须return config
  return config;
});

例如登录的config在console中打印长这个样子:

xiaomin

好了,那我们现在去检查一下别的接口在请求时,是否在请求头中携带了Authorization,在浏览器中选择Network

xiaomin

选择menus这个请求,发现它在请求头中的Authorization带了token,成功。

3、退出登录、销毁token、并跳转登录页

那么当我们退出登录时,其实就是销毁了获得的token,那么后续的请求必须生成新的token;

并且退出后跳转到登录页面

点击“退出”按钮,触发logout方法,代码如下:

logout() {
    window.sessionStorage.clear();
    this.$router.push('/login');
},

文章作者: 解你忧
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 解你忧 !
  目录