起因
产品经理对登录提出了三点要求:
1. 当用户点击记住密码时,实现7天内自动登录
2. 当用户未点击记住密码时,在浏览器窗口关闭或退出之前,用户不能掉线
3. 每次向后台发出请求时应当判断用户是否在线
业务实现逻辑
之前的同事实现这块业务使用了cookie与session。cookie存放在浏览器,方便在前端获取。
function() {
var obj = {};
obj.exist = false;
if(!(document.cookie || navigator.cookieEnabled)) {
alert("浏览器未开启cookie,网站可能无法正常使用")
return obj;
}
else {
var usercookieinfo;
var cookieName = "userinfo=";
var clist = document.cookie.split(";");
for(var i = 0; i< clist.length; i++) {
var ca = clist[i].trim();
if(ca.indexOf(cookieName) == 0) {
usercookieinfo = JSON.parse(unescape(ca.substring(cookieName.length,ca.length)));
obj.username = usercookieinfo.username;
obj.password = usercookieinfo.password;
obj.exist = true;
return obj;
}
}
return obj;
}
}
session在login的时候放入req.那么,在session未失效的时间段内,后端可以通过req.session非常方便的得到登录信息。
小x的业务逻辑如下:
1. 设置cookie的失效时间为7天。
2. 用户勾选记住密码,则存入cookie,否则本地cookie为空
3. 登录时设置session
4. 在每次向后台提起申请的时候,检查session是否过期。若没有,则继续。若失效,则检查本地cookie,若有cookie存在,在跳转到登录界面,用cookie自动登录
小x的这种方式导致的问题
- 所有向后台发起的请求都需要重复的进行验证登录,代码太冗杂
- session的时间是较短的。其中我写的某一个业务模块需要用户在界面停留较长时间,并在这个时间内不会向后台发起申请。造成,当用户长时间后发起后台申请时,页面直接跳转至登录页面,这对用户是很不好的体验
解决的办法
- [ 如何解决每次向后台发起请求时判断用户是否处于登录状态? ]
- cookie设置好后,在每次http请求时,cookie都能从req.cookies或者req.headers.cookie中获取。这是后台获取cookie的方式。当记住密码时,req.cookies存在,没有记住密码时,req.cookies不存在。因此,当login登录时, 另外设置cookie.
res.cookie("login_account", {account: login_account , password: login_pass});
这里设置的cookie并没有设置失效时间,默认为当浏览器窗口关闭,则失效。
这样一来,我们的目的就达到了。
首先设置一张黑名单。在黑名单中的模块,路由时我们对其进行拦截,并检测登录状态。session存在则放行。否则使用req.cookie来进行登录。当没有记住密码时,cookie存在于窗口关闭之前。记住密码之后,cookie存在与首次登录的7天之内。
后续的问题
- cookie本身是很小的,在本地保存的时候可以用localstorage代替。
- 在检测到cookie并用于登录时,若此时向后端发起的请求不止一个,那么其实后端是多次登录的。这个问题暂时还未解决。
- 在cookie中存放重要信息是否是安全的。对这一点有很深的疑问。