之前自己实现的项目博客中有一个关于登录的小问题存在,如果我想要直接登录之后会有一个本地的cookie用来记录登陆的状态,这样如果我刷新浏览器,也不会导致该登录状态的消失。
以上就是使用express-session实现随机产生的签名。
代码如下:
function demo(){
var chars = ['0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
var result = '';
for(var i = 0; i < 100 ; i ++) {
var id = Math.ceil(Math.random()*35);
result += chars[id];
}
return result;
}
var session=require('express-session');
app.use(session({
secret:demo(), //设置 session 签名
name:'my_blog',
// cookie:{maxAge:60*1000*60*24}, // 储存的时间 24小时
resave:false, // 每次请求都重新设置session
saveUninitialized:true
}));
之后在登录时加上一个req.session 用来存储此时登录的一个账号名。因为每一个会话的session是单独的。所以,我们只需要在每一次敏感请求之前都验证一下是否此时req.session是存在的,如果存在就说明此时其实是按照正常登录流程登录的,而不是将登录后记录登录状态的cookie复制到一个新的会话就能直接达到登录状态的效果。
代码如下:
router.beforeEach((to, from, next) => {
if (to.matched.some(res => res.meta.requireAuth)) {// 判断是否需要登录权限
if (sessionStorage.getItem('user_name')) {// 判断是否登录
Axios.post('api/main/getUser_name').then((response)=>{
if(response.data){
next();
}else{
sessionStorage.removeItem('user_name');
next({
path: '/',
})
alert('登录异常,请重新登录');
window.location.reload();
}
}).catch((err)=>{
console.log(err);
})
} else {// 没登录则跳转到登录界面
next({
path: '/',
})
alert('请先登录~');
}
} else {
next()
}
})
由于我使用的是vue-router,它自身带有路由的守卫,我可以直接在管理员的每一个操作之前都进行一次getUser_name请求,该请求就是判断此时此会话的session中是否含有已经登录后的记录。如果含有该种记录就是正常操作,否则就是非法登录,报错登陆异常后,刷新网页,并且清空session中用户自己设置的cookie。
********************************************************************************************************
其实在应用中发现了很多有意思的东西。每一个的sessionid确实都是含有的,但是我通过express-session设置的和实际的sessionid其实是不太一样的。
比如:
7NdyOA4-KHvF4o4Q43oMrQeYJcHk_SSA //req.sessionID
undefined //req.headers.cookie
Session { //req.session
cookie:
{ path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true } }
以上是我第一次进入该网页输出的部分,可以看到第一次进入网页的时候实际上并没有设置到req.headers.cookie,我的理解是第一次实际上是产生了sessionid 但是并没有设置到客户端的cookie上。也就是说只有在第一次请求之后才会有相应的cookie产生。
这样我们再刷新网页的时候会对应产生一个cookie这回才是真正使用对应的。如果我们将本地的cookie删除了,也就是说服务端没有办法认清你这个请求的来源。那么就会重新再一次发送一个新的sessionid。所以登录状态也就会相应的消失。这样问题就又返回到前面的问题了。只需要在敏感操作的时候检测一下就ok啦。
最后吐槽一下自己的智商......这次对http的响应头真的是熟悉了。。。看了一大堆攻击模式最后发现最简单的办法就在身边。我居然还想到了要不要用redis数据库来存一下这个数据。想想真的是很无语啊。
注!!!!以上均是使用vue-router + node的express-session 等实现的功能。当然还有一部分的vuex、sessionstorage等。