前言
看文章之前,强烈建议先把项目拉取下来!案例来自小弟的开源项目,这是 Token 免密登录验证的前端实现。
「项目Github」
文章内容只是个人学习的一些总结经验,不具有权威性,强烈建议先移步:
NodeJS(Express框架)实现 Token 验证免密登录 (一)
Token 免密登录前端原理
在用户第一次登录成功的时候,后端会返回一个 Token
,这个值Token
主要的作用就是用于识别用户的身份。相当于账号密码。正常情况下,前端给后端发送请求的时候,后端都需要先判断用户的身份,来返回相应的数据给用户。但我们不可能每次请求的时候都要用户输入一次账号和密码。为了便于理解,你可以看成 Token
≈ 用户输入账号和密码 (当然这不太严谨)。获取到Token
后,你需要把 Token
存在 Cookie
中。接着向服务器发送请求时,你从 Cookie
中取出 Token
,在请求头中携带上 Token
,就搞定了!
还可以用 vue-router 提供的beforeEach
方法配合 Token
进行简单的权限控制。例如:Token
过期跳转到登录页。后面说权限控制的时候再写。
安装 js-cookie 和 安装 axios (http库)
js-cookie
一个简化 cookie
增删改查的 JS 库,
//安装js-cookie
npm i js-cookie -S
//安装axios
npm i axios -S
js-cookie 和 axios 的使用比较简单,就不详细说明和例子一起看。详细文档:「js-cookie」「axios」
登录并获取 Token
我们直接看例子
import Cookies from "js-cookie";
import { adminLogin } from "@/api/api";
submit() {
this.$refs.form.validate(async (valid) => {
// valid 为 false 时,表单校验通过(element-ui Form组件)
if (!valid) return;
//调用登录接口,并把用户的账号密码传给后端
let res = await adminLogin(this.loginForm);
if (res.code !== 0) {
this.$message.error(res.msg);
} else {
//在返回的结果中获取到 token,并存放在 Cookie 中
//Cookies.set(key,data) 是 `js-cookie`提供的存放 Cookie 的方法
Cookies.set("token", res.data.token);
//Cookies.set("token", res.data.token, { expires: 7 });
//这里可以设置一下过期时间,最好比后端规定的时间早
Cookies.set("name", res.data.name);
Cookies.set("userId", res.data.userId || "");
Cookies.set("role", res.data.role);
//登录成功跳转到网站首页
this.$router.replace({ path: "/" });
}
});
},
到这里我们就已经拿到 token了。
配置 Token
KiteBlog
axios 一些全局的配置都存放在src\utils\request.js
中,所以像Token
这种几乎所有请求都需要携带的数据,放在request.js
是比较合适的。
axios
提供了拦截器的功能。详细移步:拦截器。这里只用到请求拦截器「axios.interceptors.request.use()」
,顾名思义,就是在发送请求前经进行拦截,然后修改请求的数据,例如:请求头(header)、body 等数据。 前面说过,Token
是存在请求头中的。
axios.interceptors.request.use((config) => {
//排除登录接口,登录是不需要 Token 的,只有登录了才能获取到 Token
if (config.url !== "auth/adminLogin") {
//给请求头的设置Token, Cookies.get()用于获取存放在 Cookie 的 Token
config.headers["authorization"] = `Bearer ${Cookies.get("token")}`;
}
//这一步是必须的!
return config
}, (error) => {
return Promise.reject(error);
});
这样就搞定了,是不是很简单
Token 保存在哪里比较合适? Cookie?sessionstorage?还是 localstorage ?
特意去看了一下 cookie、sessionstorage、localstorage 的特性
失效时间对比:
cookie:在不设置过期时间的时候,关闭浏览器就会进行清除。如果设置了过期时间,将以过期时间为准
sessionstorage:关闭浏览器就会进行清除,不可以设置过期时间
localstorgae:不手动清除将一致保存在浏览器中,不可以设置过期时间
储存大小对比(不同浏览器存在差异):
cookie:一般为 4k
localStorage:一般为5M
sessionStorage:一般为5M
总结:
每次请求的时候,浏览器会自动携带上 cookie 的数据,localStorage 和 sessionStorage 则不会。
从长度限制和带宽流量占用的角度来看:cookie 确实属于劣势
补充:安全性:token 存放在 cookie 中,请求的时候会自动带上cookie的信息,可能会招到 CSRF攻击,需要做好 CSRF 防御。服务器验证token时,最好取header的token,而不是为直接取cookie的信息。或者改用localStorage。
但是从设置过期时间以及免密登录的角度来考虑,cookie 要比 sessionstorag 和 localstorgae 稍微方便一些。我们可以直接判断 cookie 有没有 token ,如果有直接进入网站管理后台,而无需再次跳转到登录页,让用户输入密码。
这是说的过期是指,token 储存在浏览器 cookie 中的过期时间, 并不是 token 在后端的真正时间。 设置浏览器 cookie 过期时间是为了方便前端使用而已。
对于前端来说,最好办法就是后端但把 token 放在 cookie 里,前端不用处理,哈哈