登录授权
登录及安全
从前端看来,用户的登录和授权看起来感觉十分简单,无非就是输入用户名和密码,传给后台确认登录。但其实这里面还是有很多需要注意的问题,这里简单列举一下:
- 所有数据的传输过程应当保证安全,保证数据不会在传输过程中泄露或劫持
- 应当有一种机制来校验请求发起人是否是之前登录的用户
- 应当有一种过期机制使用户不能保持永久登录状态
以上这些问题实质上都是web开发中需要注意的安全性问题。虽然这些问题大部分由后端人员解决,前端只需要配合完成即可,但如果了解这些问题那就更好了。接下来我针对这三个问题逐条简单分析一下,期间涉及到的相关知识点大家可以自行搜索,此处不再进行深入说明(否则就变成安全介绍了)。
第一种问题的实质是数据传输的安全,防止信息泄露。针对于这种情况,目前最好的办法就是使用HTTPS,而不是使用HTTP。
第二种问题实际上是在Web开发中经常遇到的安全问题——跨站请求伪造(CSRF/XSRF)。即攻击者可以利用漏洞在其他网站上发送请求伪装成本站的正常请求,这样攻击者可以在用户完全不知情的情况下进行任何操作。这种问题目前的解决方法就是使用Token机制。当用户登录后服务端返回一个Token,之后的每次请求都要携带这个Token,如果在服务端Token不匹配则意味着授权失败。
第三种问题实际上就是为了让用户不能永久处于登录状态,否则用户登录一次就能获得永久授权。在实际中就是Token本身要具备时效性,要有过期机制。至于过期后是返回登录页面重新登录亦或是自动续期亦或是自动刷新,这就是由后端决定的了,前端只要配合好即可。
为了和后端人员配合好,前端必须做出一定的修改,接下来将说明这些的问题的前端解决方案。请注意,这些方法实质上都是对axios
的设置。
为每个请求增加Token
在上一章节中,我们其实有提到Token的携带方法,即接口权限控制部分。这里不在细说,直接上之前的代码即可。不过有一点需要注意的是Token也需要同步记录到Cookie中,否则页面刷新后,js内部的变量值将还原成初始状态。如果记录到Cookie后,则在页面刷新后可以直接从Cookie中取值,再赋给js变量。
const service = axios.create()
// http request 拦截器
// 每次请求都为http头增加Authorization字段,其内容为Token
service.interceptors.request.use(
config => {
config.headers.Authorization = `${Token}`
return config
}
);
export default service
Token超时及刷新机制
Token超时自动消失的方法可以直接通过设置Cookie的失效时间来确定。这样,在每次请求发起时,校验Cookie中是否有Token,如果没有则需要对Token进行刷新;如果有则直接请求接口即可。
而Token的刷新目前总结为两种方式:
- 每次请求时判断Token是否超时,若超时则获取新Token
- 每次请求时判断Token是否超时,若超时则跳转到授权页面
这两种方式在新Token的获取上实际并没有太大的区别,无非就是自动调用接口及跳到单独页面调用接口而已。但是如果页面中当前有多个请求被发起,那么则会出现较大的差异。前者需要对所有请求进行延迟处理,保证接口新Token的接口获取到数据后再执行之前的请求,否则这些请求将因Token超时直接失败;后者则是需要中断当前的所有的请求,并立即跳转到对应页面。
查看axios中断请求方法,在官方文档中搜索cancelToken:axios
// 第一种方式的校验函数
// 设置getToken锁,如果当前正在获取新Token, 则其他请求做延迟处理
var getTokenLock = false
function checkToken(callback){
// 检测Token是否过期
if(!hasToken()){
// 如果当前有请求正在获取Token
if(getTokenLock){
setTimeout(function(){
checkToken(callback)
}, 500)
} else {
getTokenLock = true
getNewToken().then(() => {
callback()
getTokenLock = false
})