记住我功能在各各网站是比较常见的,实现起来也都差不多,主要就是利用cookie来实现,而shiro对记住我功能的实现也是比较简单的,只需要几步即可。
Shiro提供了记住我(RememberMe)的功能,比如访问一些网站时,关闭了浏览器下次再打开时还是能记住你是谁,下次访问时无需再登录即可访问
配置步骤
- ShiroConfig.java
/**
* (新增方法)
* cookie对象;会话Cookie模板 ,默认为: JSESSIONID 问题: 与SERVLET容器名冲突,重新定义为sid或rememberMe,自定义
* @return
*/
@Bean
public SimpleCookie rememberMeCookie(){
//这个参数是cookie的名称,对应前端的checkbox的name = rememberMe
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
//setcookie的httponly属性如果设为true的话,会增加对xss防护的安全系数。它有以下特点:
//setcookie()的第七个参数
//设为true后,只能通过http访问,javascript无法访问
//防止xss读取cookie
simpleCookie.setHttpOnly(true);
simpleCookie.setPath("/");
//<!-- 记住我cookie生效时间30天 ,单位秒;-->
simpleCookie.setMaxAge(2592000);
return simpleCookie;
}
/**
* (新增方法)
* cookie管理对象;记住我功能,rememberMe管理器
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager(){
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
//rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位)
cookieRememberMeManager.setCipherKey(Base64.decode("4AvVhmFLUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
/**
* (新增方法)
* FormAuthenticationFilter 过滤器 过滤记住我
* @return
*/
@Bean
public FormAuthenticationFilter formAuthenticationFilter(){
FormAuthenticationFilter formAuthenticationFilter = new FormAuthenticationFilter();
//对应前端的checkbox的name = rememberMe
formAuthenticationFilter.setRememberMeParam("rememberMe");
return formAuthenticationFilter;
}
/**
* (修改方法)
* @Description:配置核心安全事务管理器
*/
@Bean
public SecurityManager securityManager() {
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
securityManager.setRealm(shiroRealm());
securityManager.setRememberMeManager(rememberMeManager());//(增加改行)配置记住我
return securityManager;
}
/**(修改方法)
* @Description:Filter工厂,设置对应的过滤条件和跳转条件
*/
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
……
LinkedHashMap<String, String> map= new LinkedHashMap<>();
//map.put("/**", "authc"); //(注释掉该行) 需要认证才能进行访问
map.put("/itemPage/**", "authc"); //(该行只是用来测试)/itemPage/**,必须通过认证才能访问
map.put("/**", "user"); //(增加该行) user表示配置记住我或认证通过可以访问的地址
shiroFilterFactoryBean.setFilterChainDefinitionMap(map);
return shiroFilterFactoryBean;
}
- 更改LoginController.java中login方法
//UsernamePasswordToken token = new UsernamePasswordToken(userId, password);
UsernamePasswordToken token = new UsernamePasswordToken(userId, password,rememberMe);
- UserInfo实体类实现序列化
UserInfo实体类必须实现序列化接口,否则报序列化异常。因为RememberMe会将用户信息加密然后以Cookie保存。 - 前台页面添加记住我复选框
<input type="checkbox" id="rememberMe" name="rememberMe" />记住我<br/>
获取值:rememberMe:$("#rememberMe").is(':checked')
-
测试
不记住我:
(1)使用admin登录,然后访问:http://localhost:8090/project, 不选择“记住我”,登录成功。
(2)关闭浏览器,重新打开,访问某链接:
访问 http://localhost:8090/project/resource/menu/list.do, 跳转到登录页面。
访问 http://localhost:8090/project/itemPage/listUser, 跳转到登录页面。记住我:
(1)使用admin登录,然后访问:http://localhost:8090/project, 选择“记住我”,登录成功。
(2)关闭浏览器,重新打开,访问某链接:
访问 http://localhost:8090/project/resource/menu/list.do, 访问成功。
访问 http://localhost:8090/project/itemPage/listUser, 跳转到登录页面。 -
浏览器cookie查看
我们可以使用浏览器自带的调试功能查看浏览器保存的cookie是什么样的,如下:
rememberMe 大概内容如下:
lnpEv03/s+aBSdJmuLdEXmV6Ew94uWpE0BBFzl1+XuJiWglNbmVgaYqp8n1iaUtsJnMCjmCce7zTlySFH9IaTADvKE5diAgeVW5KBUjEymMNSNH/ZYCAA3OR2LxUZMSUqVg86TK5CqkoqrpBdY7WuRA+/uIwTqQpN4CX8pHrvFz+gq2UBdqPHe8LsMWfyBZK8ueZ9uxK6FEvDk4cqmVy0pIH4+9tbwMafNNdNsAF28Mf4XT19glHU1x9XDf39pbpujuQtEUPDGAOOE+Loqxuf2hXINq5Fxiaj+TFv2Ux7Agm31ZSvtE33O8pHytA09EG8AOZVCqZUZ2KrpHk/b4OhVOwWy9zEysM0k9OcPlFqLMfcTCWeiS3fvxHvfhcRP4B1khEX3xB/HhhzZY7o+vfQAHUIbuoJ3DxAn7XgG5HFvfWY1rwt0V71Ols8lUz/BI1phYEiO79aObiw3Y78qy9i3qy342duNfl+RK5XeTrOtEpBP5F7CHCrlNC3X9OrjjeduHfcqBN5f0vEWj58wDLfMauilayDUytC0ejjFbZJUo=
其实是将用户信息加密后放到前台的(包含密码),在项目中user对象信息过于庞大,不能全部存入Cookie,Cookie对长度有一定的限制。
原文:https://blog.csdn.net/qq_34021712/article/details/80306442