SSM整合系列之 基于Shiro框架实现自动登录(RememberMe)

一、前言:Shiro框架提供了记住我(RememerMe)的功能,比如我们访问一些网站,关闭了浏览器,下次再打开还是能记住你是谁,下次访问的时候无需登录即可访问,本文将实现记住我的功能。
项目git地址:https://github.com/gitcaiqing/SSM_DEMO.git
二、大概流程:
1.首先在登录页面中选中RememerMe,然后登录成功,如果是浏览器登录,会把RememberMe的Cookie写到客户端保存下来;
2.关闭浏览器重新打开时;会发现浏览器仍然能记住;
3.访问一般的网页服务,服务端知道你是谁,且能够正常访问;
4.但如果我们访问一些特殊的敏感信息,如查看订单或者订单支付之类的操作,还是需要再次进行身份认证的,以保证当前用户还是你。
三、了解下登录认证和记住我的区别
在上一篇文章中,讲解了登录认证的简单实现,博客地址:https://blog.csdn.net/caiqing116/article/details/84637699 我们使用了如 subject.isAuthenticated()来验证用户是否进行了身份验证,然后使用Subject.login进行登录,而subject.isRemembered()表示用户是通过记住我登录的,此时可能并不真正的你(可能是别人使用了你的电脑,或者你的cookie被窃取等等)在访问。需要注意的是登录认证和记住我只能二选一,即subject.isAuthenticated() 和 subject.isRemembered()互斥。
四、具体实现
整个项目是基于之前的文章,请参考其他文章搭建整体项目,这里不重新搭建了
(1)登录页面和主页简单修改
修改内容:
①登录页如果是登录认证或记住我为真,直接跳转到主页,
②登录页添加记住我checkbox,如果选中传值true
③主页添加登录认证进入还是记住我进入的展示
login.jsp

<%@page import="com.ssm.entity.BasicUser"%>
<%@page import="org.apache.shiro.SecurityUtils"%>
<%@page import="org.apache.shiro.subject.Subject"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/common/taglib.jsp"%>
<%
	//如果登录认证或记住我,则直接跳转到主页
	Subject subject = SecurityUtils.getSubject();
	if(subject.isAuthenticated() || subject.isRemembered()){
		response.sendRedirect(request.getContextPath()+"/ssm/home");
	}

%>


登陆











 








 

	

Sign In

账号:
密码:
记住我

views/home.jsp

<%@page import="org.apache.shiro.SecurityUtils"%>
<%@page import="org.apache.shiro.subject.Subject"%>
<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>

<%@ include file="/WEB-INF/common/taglib.jsp"%>
<%
	//如果登陆成功,则直接跳转到主页
	Subject subject = SecurityUtils.getSubject();
%>



Insert title here


	

登陆成功

是否【登陆认证】访问:<%=subject.isAuthenticated() %>

是否【记住我】访问:<%=subject.isRemembered() %>

(2)登录认证实现
我们在登录的方法中接收rememberMe参数,如果为true,则说明选中了记住我,我们就可以设置usernamePasswordToken.setRememberMe(rememberMe) 这里我们对src/main/java/com/ssm/security/LoginHandler.java的方法shirologin进行修改

@RequestMapping("/shirologin")
	@ResponseBody
	public ResultModel shirologin(String username, String password, boolean rememberMe) {
		
		try {
			Subject currentUser = SecurityUtils.getSubject();
			//未认证登录
			if(!currentUser.isAuthenticated()) {
				//密码进行MD5加密
				UsernamePasswordToken usernamePasswordToken = new UsernamePasswordToken(username, EncryptKit.MD5(password));
				//是否记住我
				usernamePasswordToken.setRememberMe(rememberMe);
				//认证登陆
				currentUser.login(usernamePasswordToken);
			}
		} catch (AuthenticationException e) {
			if(e instanceof AccountException) {
				return new ResultModel(1, "账号或密码错误");
			}
		}
		return new ResultModel(0, "登陆成功");
	}

(3)修改maxAge记住我的有效时间,单位为秒
在上面我们只是设置了记住我的功能,我们猜测记住我的时长肯定有个默认值,但是我们想要修改这个时间,该如何操作,首先我们来看下设置有效时长的源码

public class CookieRememberMeManager extends AbstractRememberMeManager {

    //TODO - complete JavaDoc

    private static transient final Logger log = LoggerFactory.getLogger(CookieRememberMeManager.class);

    /**
     * The default name of the underlying rememberMe cookie which is {@code rememberMe}.
     */
    public static final String DEFAULT_REMEMBER_ME_COOKIE_NAME = "rememberMe";

    private Cookie cookie;

    /**
     * Constructs a new {@code CookieRememberMeManager} with a default {@code rememberMe} cookie template.
     */
    public CookieRememberMeManager() {
        Cookie cookie = new SimpleCookie(DEFAULT_REMEMBER_ME_COOKIE_NAME);
        cookie.setHttpOnly(true);
        //One year should be long enough - most sites won't object to requiring a user to log in if they haven't visited
        //in a year:
        cookie.setMaxAge(Cookie.ONE_YEAR);
        this.cookie = cookie;
    }
    ....
}

从中我们可以知道默认时长为一年:
public static final int ONE_YEAR = 60 * 60 * 24 * 365;
cookie.setMaxAge(Cookie.ONE_YEAR);
我们来手动配置修改这个值为30s,如下



	
	Spring Shiro整合配置文件
	
    
    
 	
        
        
    
    
    
      
	
	
    
    
    
    
    
    
    
         
    
          
    
    
    
    
        
        
        
        
        
        
        
        
            
                
            
        
      	
        
            
            	
            	/static/**= anon
            	/ssm/shirologin/** = anon
            	/ssm/logout = logout
            	/ssm/home = user
                
                /* = authc
            
        
    

  	
    
        
    
    
    
    
        
            
            	
                /ssm/home
            
        
    

需要注意一个地方就是,我们让[记住我]也有权限访问ssm/home,配置了过滤器链:/ssm/home = user
我们添加一个UserFilter的子类com/ssm/security/SysUserFilter.java

package com.ssm.security;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.web.filter.authc.UserFilter;
import org.springframework.stereotype.Service;

@Service
public class SysUserFilter extends UserFilter{ 

	@Override
	protected boolean isAccessAllowed(ServletRequest request, ServletResponse response, Object mappedValue) {
		// TODO Auto-generated method stub
		return super.isAccessAllowed(request, response, mappedValue);
	}

}

(4)登录测试
后台debug我们可以看到时长设置生效,如下图:
SSM整合系列之 基于Shiro框架实现自动登录(RememberMe)_第1张图片
通过浏览器访问我们的登录页登录
SSM整合系列之 基于Shiro框架实现自动登录(RememberMe)_第2张图片
30秒内再次访问登录页或主页
SSM整合系列之 基于Shiro框架实现自动登录(RememberMe)_第3张图片
上面两张截图充分说明了首次是登录认证,第二次进入是通过RememberMe,30秒杀后再次访问主页将跳转到登录页。
五、简单介绍退出
实现subject.logout()即可,很简单就不详细介绍了,请客观自己实现吧。

Subject subject = SecurityUtils.getSubject();
subject.logout();

你可能感兴趣的:(SSM)