一 前言
改正:x-auto-token 应改为a-auth-token
在之前,我曾发过一篇博客WebSocket的用户身份认证,主要探讨了在WebSocket中用户应该如何认证身份,其中提到了一个问题:每次发起请求服务器都会存储一个session并返回该session的Id,此处为header中的x-auto-token,长此以往,redis将被一堆无用session填满。
注意:下面我所说的redis存储session都是使用header进行认证的。
我之所以会得出这个结论是因为当初我使用了PostMan作为测试工具(浏览器也会得到同样的效果)。
当session默认使用Tomcat提供的session时,返回的JSESSIONID永远是同一个(这个结论很表象,下面会说为什么是同一个且其是怎么让咋们看到这种表象的)。
而当session使用redis进行存储时,每次涉及到session的操作时,如果有以下两种情况:
- 没有在header中将x-auto-token存放进去,
- 存放进去的x-auto-token在redis数据库中不存在
都会产生一个x-auto-token
二 正文
其实这个问题的出现很简单,涉及到的知识也比较基础,简单来说就是Cookie与Header在浏览器与PostMan中的支持方式不同。
需要强调的一点是,无论是tomcat内置的session还是spring session中的session,他们产生session条件都是一样的:
- 在客户端中使用到了关于session的操作
- 在请求中没有找到相应的JSESSIONID或者x-auto-token,或者是自定义的header字段
那么同样的session产生条件是怎样导致了不同样的结果:
在Tomcat内置的session中,浏览器中会将SESSIONID保存cookie中,这时候浏览器会自动吧JSEESION放置到header上,而PostMan上同样有着相似的功能,这就导致了其实每次发起请求时都会携带一个正确的JESSIONID,这样就会造成一个同个客户端请求的SESSION都是同一个的表象,而事实上服务器也是根据浏览器传递过来的JESSIONID来判断是否需要重新生成JESSIONID的。
那么怎样能够实现每次请求都生成不同JESSIONID的效果呢?
- 浏览器上:不保存cookie或者每次都将cookie清除
- PostMan上:每次都清除其保存的cookie
而在redis上的session认证则因为浏览器和postMan都无法提供保存header的操作,因此大部分请求都是不带x-auto-token或者是带上了错误的x-auto-token。因此就产生了众多的session。
三 解决方法
- 定时清理session,及时清除一段时间没有操作的session数据
- 在客户端对header中的x-auto-token进行存储。