进些年开发的系统大多都是采用JWT( JSON Web Token )的方式。又称为JSON
令牌,是一种用于在网络应用之间安全地传输信息的开放标准(RFC 7519)。它采用了一种紧凑的、自包含的方式来表示信息,通常用于身份验证和授权。JWT的设计目标是确保信息的完整性和安全性,同时具备易于使用和传输的特点。
JWT(JSON Web Token)相对于传统的基于 Cookie 和 Session 的身份验证方式具有以下优势:
- 无状态性(Stateless):JWT 是一种无状态的认证方式,每个请求都包含了足够的信息来验证用户身份,服务器不需要在后端存储会话信息,这样可以降低服务器的负担,也更容易实现分布式部署。
- 跨域支持:JWT 可以很方便地在不同的域名之间进行身份验证,而基于 Cookie 的身份验证受到同源策略的限制,跨域操作相对复杂。
- 安全性:JWT 可以使用签名机制来验证 token 的真实性,确保 token 没有被篡改。同时,JWT 可以将用户的一些基本信息加密在 token 中,传输过程中更加安全。
- 扩展性:JWT 可以通过自定义的声明(claim)来扩展 token 的功能,比如添加用户角色、权限等信息。而基于 Cookie 的身份验证则需要额外的逻辑来处理这些信息。
- 前后端分离:随着前后端分离开发模式的流行,使用 JWT 可以更好地适应前后端分离的架构,前端可以更方便地携带 token,并进行身份验证。
总的来说,JWT 更适合现代的 Web 应用开发,特别是在需要跨域支持、无状态性和前后端分离等场景下,JWT 的优势更加明显。然而,在一些传统的 Web 应用场景下,基于 Cookie 和 Session 的身份验证方式仍然具有一定的优势,开发者需要根据具体需求来选择适合的身份验证方式。
1.系统登录
我们拿出token来看一下
token中有第一排前半段的".“和最后一排后半段的”."将三部分结合成一个完整的token.这三部分分别是
- Header(头部)
- Payload(负载)
- Signature(签名)
执行完登录接口后,token将有前端来储存,后续再执行接口时需要携带token进行账号的身份验证。我自己写的vue项目较多,所以会存在vuex中。
2.接口权限验证
在axios的 interceptors.request(请求拦截器)中有两种添加方式
请求头中设置 Authorization
axios.interceptors.request.use(
config => {
const token = 'your_token_here';
if (token) {
config.headers.Authorization = `Bearer ${token}`;
}
return config;
},
error => {
return Promise.reject(error);
}
);
body中使用token
axios.interceptors.request.use(
config => {
const token = 'your_token_here';
if (token) {
config.data = { ...config.data, token };
}
return config;
},
error => {
return Promise.reject(error);
}
);
3.登录失败,时效过期的处理
axios.interceptors.response.use(function (response) {
let errlist = [] //1.单点登录 2.登录失败 3.时效过期 4.权限错误
let successcode = 1 //正常请求成功的code
if(errlist.includes(response.data.code)) {
//清除用户信息,缓存
//跳转登录页面
}
if(response.status === 200) {
//正常响应200应该做些什么
} else if (response.status === 200 && response.data.code != successcode){
//请求错误,接口会给出错误提示
message.error('response.data.msg');
}
return response;
}, function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
message.error('网络异常,请稍后重试');
return Promise.reject(error);
});
4.简单说一下左侧菜单的生成以及路由的构造
侧边栏都是递归循环生成,每一个栏目下是否还存在子集,存在就继续往下生成。依据菜单树的数据也是通过系统配置来的,每个账号的角色不同,每个角色的菜单的数据也会不同。系统登录之后会执行获取菜单数据的接口,咱们直接从后端的接口取配置项就行。
路由怎么和菜单匹配上呢?目前也是有两种。
1.写全量的静态路由,这样就可以保证每个访问的菜单路径在路由表里有迹可循。
2.根据后端返回的菜单树通过一定的方法转换成菜单的路由表,再拼接上部分静态路由(404,login页面等),最后用addroutes进行动态添加。
比较一下,写动态路由虽然不用去维护庞大的路由表,但是需要单写改造方法, 动态路由可能会对性能产生一定影响,特别是在处理大量动态路由时可能需要额外的计算和内存消耗,造成卡顿。
routes进行动态添加。
比较一下,写动态路由虽然不用去维护庞大的路由表,但是需要单写改造方法, 动态路由可能会对性能产生一定影响,特别是在处理大量动态路由时可能需要额外的计算和内存消耗,造成卡顿。
最后可以在 router.beforeEach 中看下访问的页面路径在菜单树里去循环比较,不存在就跳转到无权限页面。