前言
小伙伴经常会登录一些网站,比如阿里云、博客园、码云这些网站,会发现她们的登录页面会有一个记住我的选项,只要你在登录的时候勾选上,下次开机打开浏览器直接是登录状态。
原理
其实原理很简单,在用户勾选记住我进行登录时,后台根据用户唯一标识生成一串加密字符串,然后写回给浏览器到 cookie 并存留一段时间,用户下次重新打开浏览器,会发现浏览器是记住你的。
关于 cookie,后台对用户对象序列化并加密,当重新请求时,后台能够获取反序列化且解密之后的用户对象。
集成
前台登录:
<form class="layui-form" action="javascript:void(0);">
<div class="layui-form-item">
<img class="logo" src="images/logo_new.png" />
<div class="title">SP Admin</div>
<div class="desc">
青 岛 市 最 具 影 响 力 的 开源项目 之 一
</div>
</div>
<div class="layui-form-item">
<input name="username" type="text" placeholder="账 户" value="admin" hover class="layui-input" />
</div>
<div class="layui-form-item">
<input name="password" type="password" placeholder="密 码" value="admin" hover class="layui-input" />
</div>
<div class="layui-form-item">
<input placeholder="验证码" name="verCode" hover class="code layui-input layui-input-inline" />
<img src="/sys/captcha" class="codeImage" id="captchaImage"/>
</div>
<div class="layui-form-item">
<input type="checkbox" name="rememberMe" value="true" title="记住密码" lay-skin="primary">
</div>
<div class="layui-form-item">
<button class="pear-btn pear-btn-success login" lay-submit lay-filter="login">
登 入
</button>
</div>
</form>
后台登录:
/**
* 登录
*/
@PostMapping("/login")
@ResponseBody
public Result login(String username, String password,String verCode,
boolean rememberMe,HttpServletRequest request){
try{
if (CaptchaUtil.ver(verCode, request)) {
Subject subject = ShiroUtils.getSubject();
password = MD5Utils.encrypt(username, password);
UsernamePasswordToken token = new UsernamePasswordToken(username, password, rememberMe);
subject.login(token);
}else{
CaptchaUtil.clear(request);
return Result.error(400,"验证码错误");
}
}catch (Exception e) {
e.printStackTrace();
return Result.error("登录失败");
}
return Result.ok("登录成功");
}
配置文件 ShiroConfig 追加以下代码:
@Bean
public ShiroFilterFactoryBean shiroFilterFactoryBean (SecurityManager securityManager) {
ShiroFilterFactoryBean shiroFilterFactoryBean = new ShiroFilterFactoryBean();
shiroFilterFactoryBean.setSecurityManager(securityManager);
shiroFilterFactoryBean.setLoginUrl("/login.html");
shiroFilterFactoryBean.setUnauthorizedUrl("/403");
Map<String, Filter> filtersMap = new LinkedHashMap<>();
filtersMap.put("kickout", kickoutSessionControlFilter());
shiroFilterFactoryBean.setFilters(filtersMap);
Map<String, String> filterChainDefinitionMap = new LinkedHashMap<>();
/**
* 静态文件
*/
filterChainDefinitionMap.put("/css/**","anon");
filterChainDefinitionMap.put("/lib/**","anon");
filterChainDefinitionMap.put("/data/**","anon");
filterChainDefinitionMap.put("/images/**","anon");
filterChainDefinitionMap.put("/js/**","anon");
filterChainDefinitionMap.put("/file/**","anon");
/**
* 登录注册
*/
filterChainDefinitionMap.put("/login.html","anon");
filterChainDefinitionMap.put("/sys/logout","anon");
filterChainDefinitionMap.put("/sys/login","anon");
filterChainDefinitionMap.put("/sys/register","anon");
filterChainDefinitionMap.put("/sys/captcha","anon");
/**
* authc:所有的url都不许,认证通过后才可以访问;
* anon:所有的url都可以匿名访问
* user:表示记住我或认证通过才可以访问
*/
filterChainDefinitionMap.put("/**", "kickout,user");
shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap);
return shiroFilterFactoryBean;
}
/**
* cookie管理对象
* @return
*/
@Bean
public CookieRememberMeManager rememberMeManager(){
CookieRememberMeManager cookieRememberMeManager = new CookieRememberMeManager();
cookieRememberMeManager.setCookie(rememberMeCookie());
cookieRememberMeManager.setCipherKey(Base64.decode("4BxVhuFKUs0KTA3Kprsdag=="));
return cookieRememberMeManager;
}
@Bean
public SimpleCookie rememberMeCookie(){
SimpleCookie simpleCookie = new SimpleCookie("rememberMe");
simpleCookie.setHttpOnly(true);
simpleCookie.setPath("/");
simpleCookie.setMaxAge(259200);
return simpleCookie;
}
需要说明的是:
如果是用户正常登录
subject.isRemembered()==false
subject.isAuthenticated()==true
如果是通过记住我登录
subject.isRemembered()==true
subject.isAuthenticated()==false
另外对于拦截器的配置:
authc:所有的url都不许,认证通过后才可以访问
anon:所有的url都可以匿名访问
user:表示记住我或认证通过才可以访问
如果你开启了记住我的选项,需要使用 user 进行拦截。
案例
登录地址:https://tools.cloudbed.vip
账号密码:admin admin2020
记住密码登录,然后关闭浏览器,重新打开浏览器进入以上网址,如果直接进入后台说明记住成功。
源码:gitee.com/52itstyle/SPTools
版权声明:本文为zhulin2012原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。