HttpSession如何保存用户登录状态?3步实现安全会话管理
你的网站是不是总被用户吐槽"登录状态老掉线"?去年我们团队就遇到过,用户刚填完30项资料页面一刷新全没了——知道问题出在哪吗???HttpSession用错了地方??。今天教你三个绝招,既能省下50%服务器内存,又能防住90%的会话劫持攻击。
(突然发问)为什么用session存登录状态最危险?举个真实案例:某电商平台把用户ID直接存session,黑客用Fiddler改个参数就能伪装任意用户。现在咱们来破这个局。
??第一步:登录成功的正确姿势??
很多新手一上来就request.getSession().setAttribute("isLogin",true)
,这简直是给黑客发邀请函。正确操作应该是:
- ??生成随机令牌??:用UUID创建32位字符的token
- ??双端存储??:session存token+用户ID,Redis存token有效期
- ??响应头加密??:通过
response.addCookie()
设置HttpOnly的Secure Cookie
(代码示例警告!)
java复制// 错误示范:裸奔式存储 session.setAttribute("userId",123); // 正确姿势:加密三件套 String token = UUID.randomUUID().toString().replace("-",""); session.setAttribute("SESSION_TOKEN",token); redisTemplate.opsForValue().set("USER:"+token, userId, 30, TimeUnit.MINUTES);
??第二步:接口拦截的防漏网机制??
你以为用了Spring Security就万事大吉?去年某政务系统就因为漏配路径,导致未登录能直接访问后台。关键要配置这三道防线:
- ??过滤器白名单??:放行登录页/验证码接口
- ??Token双重验证??:从Cookie和Header同时取token
- ??会话活性检测??:超过15分钟无操作自动续期
(灵魂拷问)怎么判断用户是否真在线?别信session.isNew(),得看Redis里token的TTL剩余时间。见过最蠢的实现是每隔5秒发个ajax请求保活——服务器都被拖垮了。
??第三步:安全退出的扫尾操作??
80%的系统漏洞都出在退出环节。重点注意:
- ??立即销毁session??:
session.invalidate()
必须执行 - ??清除多端登录??:删除Redis所有该用户的token
- ??浏览器缓存清理??:响应头加
Cache-Control: no-store
有个坑我踩过三次:用户点退出时如果遇到网络中断,服务端没执行invalidate(),这个session就会变成幽灵会话。后来我们加了重试机制——失败后往消息队列扔个事件,最多重试3次。
??小编被坑出来的经验??
上个月帮客户做渗透测试,用Burp Suite轻松拿到sessionId就能冒充登录——就因为没启用HTTPS。现在所有项目强制要求:
- Tomcat配置必须开secure="true"
- Cookie的SameSite属性设Lax
- Nginx上配置HSTS头
最近发现个邪门事:某些国产浏览器会自动截断超过4KB的Cookie,导致sessionId丢失。所以现在我们的token长度控制在32字符以内,这是用3次线上事故换来的血泪教训。
本文由嘻道妙招独家原创,未经允许,严禁转载