通过登录保留状态研究一下http的响应头及session
之前自己实现的项目博客中有一个关于登录的小问题存在,如果我想要直接登录之后会有一个本地的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等。