当前位置: 首页 > news >正文

Java Web实现“十天内免登录”功能

Java Web实现“十天内免登录”功能

一、 功能原理

“十天内免登录”的本质是在客户端(浏览器)持久化一个加密的、唯一的身份凭证,从而让服务器在用户关闭浏览器再次打开时,依然能够识别出他的身份。

其核心流程如下图所示:

flowchart TDA[用户登录] --> B{选择'十天内免登录'?}B -- 是 --> C[服务器生成Token<br>(用户名+随机数+过期时间)]B -- 否 --> D[结束]C --> E[Token与用户关联并存储至数据库]C --> F[Token加密后写入用户浏览器Cookie]E --> G[完成登录]F --> GH[用户再次访问] --> I[服务器读取Cookie中的Token]I --> J{Token验证是否有效?<br>(存在、未过期、匹配)}J -- 无效或不存在 --> K[视为未登录]J -- 有效 --> L[自动登录<br>并根据Token查询对应用户]L --> M[为用户创建登录会话Session]M --> N[完成自动登录]

二、 实现步骤(基于Token方案)

这是一种安全且常用的方案。

  1. 数据库准备

    • 在用户表中添加两个字段(或使用单独的表):
      • remember_token (VARCHAR):用于存放唯一的令牌字符串。
      • token_validity (DATETIME/TIMESTAMP):用于存放令牌的过期时间。
  2. 登录成功后的处理

    • 用户登录时,如果勾选了“十天内免登录”,服务器除了正常创建Session之外,还需要:
      • 生成一个唯一且加密安全的随机令牌 (Token)。
      • 计算过期时间(如:当前时间 + 10天)。
      • 将令牌和过期时间与当前用户关联,并存入数据库
      • 将令牌和用户名(或用户ID)通过Cookie发送给客户端浏览器
  3. 自动登录的过滤与验证

    • 编写一个Filter或Interceptor,在用户访问网站时进行拦截检查。
    • 检查顺序
      1. 检查请求中是否已有有效的Session?如果有,直接放行。
      2. 如果没有Session,则检查客户端是否携带了“记住我”的Cookie。
      3. 如果找到了Cookie,则从中解析出令牌和用户名。
      4. 根据用户名/用户ID到数据库中查找有效的令牌和过期时间。
      5. 验证:令牌是否存在、是否匹配、是否未过期。
      6. 如果验证通过:则自动为用户创建一个新的Session,视为已登录,然后放行。
      7. 如果验证失败:则删除客户端无效的Cookie,并让其保持未登录状态。
  4. 退出登录的处理

    • 用户点击退出时,除了要无效化(invalidate)当前的Session,还需要:
      • 删除数据库中对该应用户的令牌记录
      • 删除客户端浏览器中存储“记住我”的Cookie(通过设置一个同名的、值为null的、过期时间为0的Cookie来实现)。

三、 核心代码示例

1. 生成并存储Token(登录Servlet中)

// ... 用户密码验证成功后 ...
if ("on".equals(request.getParameter("rememberMe"))) { // 判断是否勾选// 1. 生成随机TokenString token = UUID.randomUUID().toString() + ThreadLocalRandom.current().nextLong();// 更安全的做法是使用 SecureRandom// 2. 计算过期时间 (10天后)long validity = System.currentTimeMillis() + (1000L * 60 * 60 * 24 * 10); // 毫秒Date expiryDate = new Date(validity);// 3. 将Token和过期时间存入数据库(关联对应用户)userService.updateRememberToken(currentUser.getId(), token, expiryDate);// 4. 创建Cookie并发送给客户端Cookie cookie = new Cookie("rememberMe", token);cookie.setMaxAge(60 * 60 * 24 * 10); // 秒为单位,10天cookie.setPath("/"); // 设置为全站有效cookie.setHttpOnly(true); // 防止XSS攻击获取Cookie,重要!// cookie.setSecure(true); // 如果使用HTTPS,请启用此选项response.addCookie(cookie);
}// 正常创建Session
HttpSession session = request.getSession();
session.setAttribute("user", currentUser);
response.sendRedirect("home.jsp");

2. 自动登录过滤器 (AutoLoginFilter)

@WebFilter("/*") // 拦截所有请求
public class AutoLoginFilter implements Filter {@Overridepublic void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException {HttpServletRequest request = (HttpServletRequest) req;HttpServletResponse response = (HttpServletResponse) resp;HttpSession session = request.getSession(false); // 获取现有session,不创建新session// 1. 如果用户session已存在,直接放行if (session != null && session.getAttribute("user") != null) {chain.doFilter(request, response);return;}// 2. 检查Remember-Me CookieCookie[] cookies = request.getCookies();String rememberMeToken = null;if (cookies != null) {for (Cookie cookie : cookies) {if ("rememberMe".equals(cookie.getName())) {rememberMeToken = cookie.getValue();break;}}}// 3. 如果找到了Cookieif (rememberMeToken != null) {// 调用Service,通过Token查找用户信息(包含过期时间)User user = userService.findByRememberToken(rememberMeToken);// 4. 验证Token和用户是否存在且未过期if (user != null && user.getTokenValidity().after(new Date())) {// 验证成功,自动为用户创建Sessionsession = request.getSession();session.setAttribute("user", user);// 可以选择更新Token有效期(滑动过期时间)} else {// Token无效或已过期,删除客户端的Cookieif (user == null) {// 数据库无此Token,清理无效CookieCookie cookie = new Cookie("rememberMe", null);cookie.setMaxAge(0);cookie.setPath("/");response.addCookie(cookie);}}}// 5. 继续执行后续的过滤器或请求chain.doFilter(request, response);}
}

四、 安全考量与最佳实践

  1. Token必须是不可预测的:使用SecureRandomUUID生成高熵(高随机性)的令牌,防止攻击者暴力猜测。
  2. HttpOnly Cookie:设置Cookie的HttpOnly属性为true,防止JavaScript窃取Cookie(防御XSS攻击)。
  3. Secure Cookie:如果你的网站使用HTTPS,务必设置Cookie的Secure属性为true,保证Cookie只在加密通道中传输。
  4. 令牌仅使用一次:更安全的做法是每次自动登录后都生成一个新的令牌替换掉旧的,并更新数据库和Cookie。
  5. 关联用户ID而非用户名:在Cookie中,可以存储userId:token的组合,而不是username:token,因为ID通常是不可变的,且更难被枚举。
  6. 重要操作需重新认证:即使用户通过“记住我”功能保持了登录状态,在进行修改密码、支付等敏感操作时,应要求用户重新输入密码进行验证。
  7. 提供注销选项:一定要提供明显的“退出登录”功能,并正确清理Session和Cookie。

通过以上步骤,你就可以在Java Web项目中实现一个相对安全可靠的“十天内免登录”功能了。


文章转载自:

http://d7rYyne4.kbqws.cn
http://nNg4KAza.kbqws.cn
http://6gnyxlnG.kbqws.cn
http://8Qd9GyCc.kbqws.cn
http://OhxCUY6B.kbqws.cn
http://YnqAfExH.kbqws.cn
http://Df4zX7nk.kbqws.cn
http://NWBYHldJ.kbqws.cn
http://WibBwNhb.kbqws.cn
http://OPT7Mqnb.kbqws.cn
http://tCT5G5oA.kbqws.cn
http://Cn5bFtKq.kbqws.cn
http://NuUnyrzS.kbqws.cn
http://RdpvibzA.kbqws.cn
http://h2yKF0xU.kbqws.cn
http://dXtoJR7v.kbqws.cn
http://aJFZxVgb.kbqws.cn
http://Pqni3OzP.kbqws.cn
http://Q2Wbc9fI.kbqws.cn
http://4c5AEyDM.kbqws.cn
http://s0psq80Q.kbqws.cn
http://1X0mrmBb.kbqws.cn
http://66FdWbM6.kbqws.cn
http://5l3r4tVG.kbqws.cn
http://bjoS5aga.kbqws.cn
http://Nzr40VMM.kbqws.cn
http://4XHixoWe.kbqws.cn
http://4iSBg0lG.kbqws.cn
http://xnGZUvii.kbqws.cn
http://pQN9XD0D.kbqws.cn
http://www.dtcms.com/a/378612.html

相关文章:

  • CH347使用笔记:CH347在Vivado下的使用教程
  • 【linux内存管理】【基础知识 1】【pgd,p4d,pud,pmd,pte,pfn,pg,ofs,PTRS概念介绍】
  • 详解mcp以及agent java应用架构设计与实现
  • 硬件开发2-ARM裸机开发2-IMX6ULL
  • 电商网站被DDoS攻击了怎么办?
  • Java NIO的底层原理
  • QT 常用控件(概述、QWidget核心属性、按钮类控件、显示类控件、输入类控件、多元素控件、容器类控件、布局管理器)
  • MATLAB2-结构化编程和自定义函数-台大郭彦甫视频
  • 鸿蒙的编程软件的介绍
  • 鸿蒙审核问题——Scroll中嵌套了List/Grid时滑动问题
  • REDPlayer 鸿蒙原生视频播放库组件介绍与使用指南
  • HarmonyOS 应用开发深度解析:ArkUI 声明式 UI 与现代化状态管理最佳实践
  • redis 入门-1
  • Json-rpc通信项目(基于C++ Jsoncpp muduo库)
  • TODO的面试(dw三面、sqb二面、ks二面)
  • Vibe Coding实战项目:用Qwen3-Coder做了个AI跳舞视频生成器
  • Vue 封装Input组件 双向通信
  • 【混合开发】进阶到【大前端++】
  • ZooKeeper Java客户端与分布式应用实战
  • 【复习】计网每日一题---传输层无连接不可靠服务
  • 2025年秋招答疑:AI面试如何破解在线作弊难题?
  • KafKa01:在Windows系统上安装Kafka
  • 【Big Data】Amazon S3 专为从任何位置检索任意数量的数据而构建的对象存储
  • C++:模版进阶
  • 【Canvas与旗帜】圆角红面白边蓝底梅花五星旗
  • 不同局域网远程桌面连接:设置让外网电脑直接windows自带远程桌面访问内网计算机,简单3步实现通用详细教程
  • set 认识及使用
  • 如何打造“高效、安全、精准、可持续”的智能化实验室?
  • 究竟什么时候用shared_ptr,什么时候用unique_ptr?
  • 前端抽象化,打破框架枷锁:react现代化项目中的思想体现