Springboot实现remember-me记住我功能
1.什么是remeber-me?
remeber-me即记住我
功能,是我们在登录web系统时的常见勾选项。当我们登录一个web系统时除了输入常规的用户名、密码后还可以勾选记住我选项(假设该系统提供了该选项),此时假设用户名、密码输入正确那么系统将会在客户浏览器cookie中记录用户登录相关认证相关信息。实现的效果就是当我们下次再次访问该网站某些页面时无需再次登录。
2.rember-me实现原理
2.1 登录过程中记住我流程:
2.2 直接访问系统目标页,服务端验证流程:
2.3 退出流程
删除cookie,销毁session。
3.使用springboot实现步骤
本文为了快速演示记住我功能将采取服务端硬编码方式代替数据库存储,表达的原理一致就Ok。
只列出关键部分代码,详细请看文章结尾源码链接查看完整代码。
3.1 创建用户模型
@Data
public class SysUser {
private String username;
private String password;
private Integer rememberMe;
}
3.2 创建登录控制器
@Controller
@Slf4j
public class LoginController {
@RequestMapping("/login")
public String loginPage(){
return "login";
}
@RequestMapping("/index")
public String index(){
return "index";
}
@PostMapping("/dologin")
public String login(SysUser user,
HttpServletRequest request,
HttpServletResponse response,
Model model){
// 判断用户名密码
if(!("admin".equals(user.getUsername()) && "admin".equals(user.getPassword()))){
return "redirect:login";
}
// 认证成功,向session中添加用户信息
HttpSession session = request.getSession();
session.setAttribute("user",user);
// 判断是否勾选了记住我
if(user.getRememberMe()!=null){
// 为了演示方便token写死,为用户名:admin的base64编码
Cookie cookie = new Cookie("boot_rememberMe", "YWRtaW4=");
// 为了演示设置cookie过期时间为30s
cookie.setMaxAge(30);
response.addCookie(cookie);
}
return "redirect:index";
}
@GetMapping("/logout")
public String logout(HttpServletRequest request, HttpServletResponse response){
HttpSession session = request.getSession();
if (null == session || session.getAttribute("user") == null) {
return "login";
}
session.invalidate();
Cookie[] cookies = request.getCookies();
if (ObjectUtils.isEmpty(cookies)) {
} else {
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (name.equals("boot_rememberMe")) {
cookie.setMaxAge(0);
response.addCookie(cookie);
}
}
}
return "login";
}
}
3.3 创建RememberFilter
@Slf4j
@Component
public class RememberFilter implements Filter {
private String[] noFilterArray=new String[]{"/login","/dologin"};
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain filterChain) throws IOException, ServletException {
List<String> noFilterList= Arrays.asList(noFilterArray);
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String requestURI = req.getRequestURI();
requestURI = requestURI.substring(requestURI.lastIndexOf("/"));
// 判断是否为不需要过滤请求
if (noFilterList.contains(requestURI)) {
filterChain.doFilter(request,response);
}else{
HttpSession session = req.getSession();
if (null==session||session.getAttribute("user")==null) {
Cookie[] cookies = req.getCookies();
if (ObjectUtils.isEmpty(cookies)) {
((HttpServletResponse) response).sendRedirect(req.getContextPath()+"/login");
return;
} else {
SysUser user = null;
for(Cookie cookie:cookies){
String name = cookie.getName();
if (name.equals("boot_rememberMe")) {
String value = cookie.getValue();
// 演示采用硬编码,实际需要和数据库中token比较
if (!value.equals("YWRtaW4=")) {
Cookie cookie1=new Cookie("boot_rememberMe",null);
cookie1.setMaxAge(0);
res.addCookie(cookie1);
}else{
user = new SysUser();
user.setUsername("admin");
user.setPassword("admin");
user.setRememberMe(1);
session.setAttribute("user", user);
log.info("从cookie中获取user放入session");
}
}
}
if(user==null){
((HttpServletResponse) response).sendRedirect(req.getContextPath()+"/login");
return;
}
}
}
filterChain.doFilter(request,response);
}
}
}
3.4 创建登录页
<form action="/dologin" method="post" th:action="@{/dologin}">
<div class="title">
<h1>后台管理系统</h1>
</div>
<div class="form-item">
<label for="username">用户名:</label>
<input type="text" id="username" name="username" />
</div>
<div class="form-item">
<label for="password">密码:</label>
<input type="text" id="password" name="password" />
</div>
<div class="form-item">
<input type="checkbox" id="rememberMe" name="rememberMe" value="1"/>记住我
<input type="checkbox" name="rememberMe" hidden="hidden">
</div>
<div class="form-item">
<button type="submit" id="submit" class="btn btn-primary">
登录
</button>
</div>
</form>
3.5 创建首页
<body>
欢迎,<span th:text="${session.user.username}"></span>
<a href="" th:href="@{/logout}">退出</a>
</body>
4.测试
输入地址:localhost:9000/login
,用户名:admin
,密码:admin
4.1 不勾选记住我
不勾选就是简单的登录退出功能。
4.2 勾选记住我
- 成功登陆后,关闭浏览器
- 30s内再次打开浏览器输入首页地址发现可以直接访问
- 30s后再次访问首页发现cookie失效直接跳转到登录页
- 退出后cookie失效,无法再次访问首页
4.3 相关截图
- 首页
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构