之前有段时间,频繁收到alova的用户们反馈如何实现像axios一样的token无感刷新功能,这个功能确实比较麻烦,相信大家都深有体会。
每次都要去重复实现真的让我很压抑。于是乎一怒之下,我决定写一个通用的token认证模块,为的就是让alova的用户们再也不要为这个事情发愁了。
使用alova的Token认证拦截器可以完美为你解决以下问题:
- 统一维护 Token 身份认证的所有代码,包括登录、登出、token 附带、token 刷新等;
- 支持在客户端和服务端验证 token 过期,并无感刷新 token;
- 依赖 token 的请求自动等待 token 刷新完成再请求;
- 自动放行不依赖 token 的访客请求;
你唯一要做的就是配置一下请求接口的角色类型,然后其他的会自动帮你搞定。
可能有些人有所不知,简单介绍下,alova是一个请求策略库,用法类似axios,但你可以通过简单配置参数,即可实现复杂请求如请求共享、分页请求、表单提交、断点续传等,无需编写大量代码,提高开发效率,应用性能,减轻服务端压力。
Token 身份认证模块是alova的其中一个请求模块,它是通过全局的拦截器完成的,分别提供了基于客户端和服务端的身份认证。
- 基于客户端的身份认证:表示从客户端判断 token 是否过期,例如在登录时获取到的 token 过期时间;
- 基于服务端的身份认证:表示从服务端返回的状态判断 token 是否过期,例如
status
为 401 时表示过期;
接下来我们以基于服务端的身份认证为例聊一聊吧。
先安装一下依赖
bash
# vue
npm install alova @alova/scene-vue --save
# react
npm install alova @alova/scene-react --save
# svelte
npm install alova @alova/scene-svelte --save
在服务端实现无感刷新 Token
当服务端返回的状态为token过期时(例如401)即表示需要重新刷新token了,此时也会让刷新过程中发起的请求等待着。
javascript
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication({
refreshTokenOnSuccess: {
// 响应时触发,可获取到response和method,并返回boolean表示token是否过期
// 当服务端返回401时,表示token过期
isExpired: response => {
return response.status === 401;
},
// 当token过期时触发,在此函数中触发刷新token
handler: async (response, method) => {
const { token, refresh_token } = await refreshToken();
localStorage.setItem('token', token);
localStorage.setItem('refresh_token', refresh_token);
}
}
});
它将会返回两个拦截器函数,我们可以分别绑定到alova的全局请求拦截器和响应拦截器上就可以了。
javascript
import { createServerTokenAuthentication } from '@alova/scene-*';
import { createAlova } from 'alova';
const { onAuthRequired, onResponseRefreshToken } = createServerTokenAuthentication({
// ...
});
const alovaInstance = createAlova({
// ...
beforeRequest: onAuthRequired(method => {
// ...原请求前拦截器
}),
responded: onResponseRefreshToken((response, method) => {
//...原响应成功拦截器
return response.json();
})
});
最后,为了让refreshToken
请求不被拦截下来,还需要通过元数据标识authRole
为refreshToken
。
了解更多元数据的信息,请前往method 元数据。
javascript
export const refreshToken = () => {
const method = alovaInstance.Get('/refresh_token');
method.meta = {
authRole: 'refreshToken'
};
return method;
};
这样,一个完整的token无感刷新功能就完成了
放行访客请求
有些接口不需要依赖 token 认证,我们称它们为"访客请求",此时我们可以设置它们的元数据为authRole: null
来绕过前端的拦截,让它们顺利发出请求和接收响应。
javascript
export const requestTokenNotRequired = () => {
const method = alovaInstance.Get('/token_not_required');
method.meta = {
authRole: null
};
return method;
};
最后
除此以外,token认证请求模块还有登录拦截、登出拦截等功能,让登录认证功能更加简单。token认证模块详细文档在此。
有任何问题,你可以加入以下群聊咨询,也可以在github 仓库中发布 Discussions,如果遇到问题,也请在github 的 issues中提交,我们会在最快的时间解决。
同时也欢迎贡献你的一份力量,请移步贡献指南。