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查看如下:

 


下面考虑第二个问题,

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中打印长这个样子:

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

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

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

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

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

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

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

欢迎交流、指正!

参考博客:

Window 对象 | 菜鸟教程

Vue项目中实现用户登录及token验证 - 一抹夏忧☆ - 博客园

Java Token的原理和生成使用机制_Jbase的博客-CSDN博客_java token

【Vue】实战项目:电商后台管理系统(Element-UI)(一)前后端搭建 - 登录界面 - 主页界面_YK菌的博客-CSDN博客

Logo

前往低代码交流专区

更多推荐