关于登录权限的设置--用过滤器解决的方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_40480741/article/details/82690771

需求:在项目开发中,按照正常的思路:用户必须登录了才能进入到后台,如何知道后台的地址而直接访问后台,那么该项目可以说是非常的差劲了。由于开发需要,我这几天学习和解决了这个问题。现在分享出现,希望能给大家带来帮助!

1、写SessionFilter (自定义)过滤器,要实现Filter接口

import java.io.IOException;
import java.util.regex.Pattern;
import java.net.URLEncoder;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang.StringUtils;

public class SessionFilter implements Filter{

   /**要检查的 session 的名称 */
   private String sessionKey;
    
   /**需要排除(不拦截)的URL的正则表达式 */
   private Pattern excepUrlPattern;
    
   /**检查不通过时,转发的URL */
   private String forwardUrl;

   public void init(FilterConfig cfg) throws ServletException{
       System.out.println("SessionFilter的启动");
       sessionKey= cfg.getInitParameter("sessionKey");
       String excepUrlRegex = cfg.getInitParameter("excepUrlRegex");
       if (!StringUtils.isBlank(excepUrlRegex)){
           excepUrlPattern= Pattern.compile(excepUrlRegex);
       }
       forwardUrl= cfg.getInitParameter("forwardUrl");
   }

   public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException,
       ServletException {
       System.out.println("执行SessionFilter过滤");
       //如果 sessionKey 为空,则直接放行(个人觉得在此这个判断条件没有用)
       if (StringUtils.isBlank(sessionKey)){
           chain.doFilter(req,res);
           return;
       }

        /* 请求 http://127.0.0.1:8080/sm/index.jsp?&a=1&b=2 时
         * request.getRequestURL(): http://127.0.0.1:8080/sm/index.jsp
         * request.getContextPath(): /sm 
         * request.getServletPath():/index.jsp
         * request.getRequestURI(): /sm/index.jsp
         * request.getQueryString():a=1&b=2
         */
       HttpServletRequest request = (HttpServletRequest) req;
       HttpServletResponse response = (HttpServletResponse) res;
       String servletPath = request.getServletPath();
       System.out.println("servletPath="+servletPath);
       //如果请求的路径与forwardUrl相同,或请求的路径是排除的URL时,则直接放行
       if (servletPath.equals(forwardUrl)|| 
               excepUrlPattern.matcher(servletPath).matches()) {
           chain.doFilter(req,res);
           return;
       }

  //注意:adminName为用户登录名,必须在登录信息传到后台时放到Session

  //里,我的项目在@Controller的登录用户传到后台时当判断用户名和密码正确

  //后立马到Session里,作用是用来判断Session如果还有效,返回不为空,可以在后台继续操作;如果超时
  //了,返回null,则跳到登录页面

       Object sessionObj = request.getSession().getAttribute("adminName");
       System.out.println("sessionObj="+sessionObj);
       //如果Session为空,则跳转到指定页面
       if (sessionObj== null){
           String contextPath = request.getContextPath();
           String redirect = servletPath + "?" +StringUtils.defaultString(request.getQueryString());
           System.out.println("contextPath="+contextPath+",redirect="+redirect);
           response.sendRedirect(contextPath+ StringUtils.defaultIfEmpty(forwardUrl, "/")
                           +"?redirect=" +URLEncoder.encode(redirect, "UTF-8"));
       }else {
           chain.doFilter(req,res);
       }
   }

   public void destroy(){
       System.out.println("SessionFilter的销毁");
   }
}

文字有一处要注意:即

 Object sessionObj = request.getSession().getAttribute("adminName");

中的“adminName”要在后台有设置,否则不起作用,比如我在Controller中这样设置

2、在web.xml中配置如下过滤器信息(重点在如何哪些需要拦截,哪些不需要拦截)

<!-- 检查用户是否登录了系统的过滤器配置 开始 -->
	<filter>
		<filter-name>SessionFilter</filter-name>
		<filter-class>com.py.util.wrb.SessionFilter</filter-class>
		<init-param>
			<description>
			将当前登录的用户的信息保存在session 中时使用的key,如果没有配置此参数,则该过滤器不起作用
			</description>
			<param-name>sessionKey</param-name>
			<param-value>adminName</param-value>
		</init-param>
		<init-param>
			<description>
			 如果用户未登录(即在session 中 key 为 sessionKey 的属性不存在或为空),则将请求重定向到该 url。
			 该url 不包含web应用的 ContextPath。如果不配置此参数,则在用户未登录系统的情况下,
			 直接重定向到web应用的根路径(/)
     		</description>
			<param-name>forwardUrl</param-name>
			<param-value>/index.jsp</param-value>
		</init-param>
		<init-param>
			<description>
         	  不需要进行拦截的url 的正则表达式,即:如果当前请求的 url 的 servletPath 能匹配该正则表达式,则直接放行(即使未登录系统)。
        	  此参数的值一般为loginServlet 和 registServlet 等。另外,参数redirectUrl 的值不用包含在该正则表达式中,因为 redirectUrl 对应的 url 会被自动放行。
       		  还有一点需要说明的是,该参数的值不包含web应用的ContextPath。
     		</description>
			<param-name>excepUrlRegex</param-name>
			<!-- 不需要拦截的路径 
				(login_login_execute|login_2_login).do
                会在后面有详细的解释
			-->
			<param-value>/(jumpIndex|loginAdmin)</param-value>
		</init-param>
	</filter>
<!-- /* 表示所有的都要进行过滤-->
	<filter-mapping>
		<filter-name>SessionFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>

耐心讲解:打个比方,如果你登录你的系统要输入这样的地址进入登录界面:

http://127.0.0.1:8080/sm/index.jsp

那么forwardUrl应该是这样写,代码页面的登录页面(forwardUrl可自定义名称,当然要见词知意最好,下同)

<param-name>forwardUrl</param-name>
<param-value>/index.jsp</param-value>

在一个系统中,我们一般把登录页面放在web-inf的外面,否则直接访问不了(个人见解),为了起到保护作用,我们在登录页面点击登录,要做一些路径跳转,有多个跳转就有多少个路径,直到后台的主界面,这些路径也必须不能拦截,否则你登录不到后台。如下,这里说明登录到后台要经过jumpIndex和loginAdmin路径,“|”代表“或”。

<description>
         	  不需要进行拦截的url 的正则表达式,即:如果当前请求的 url 的 servletPath 能匹配该正
                则表达式,则直接放行(即使未登录系统)。
        	  此参数的值一般为loginServlet 和 registServlet 等。另外,参数redirectUrl 的值不用
              包含在该正则表达式中,因为 redirectUrl 对应的 url 会被自动放行。
       		  还有一点需要说明的是,该参数的值不包含web应用的ContextPath。
</description>
<param-name>excepUrlRegex</param-name>
<param-value>/(jumpIndex|loginAdmin)</param-value>

3、为了方便测试,最好设置Session的有效时间短一点,如何设置Session有效时间百度有一大堆,我是在web.xml重配置的,如:我设置有效时间为1分钟

<session-config>
		<session-timeout>1</session-timeout>
</session-config>

这样可以在Session失效后直接登录后台看是否进得去

比如我登录后台后的一个路径为:http://127.0.0.1:8080/sm/camera

当Session失效后在新的地址栏上输入:http://127.0.0.1:8080/sm/camera

看是否能进入。进不去,说明过滤器起作用了。

至此完成,有什么问题可以留言,我会及时回复!后面我会继续完善这篇文章,希望各位能给点指点,谢谢!

声明:我通过百度上找很多资料,结合自己项目做的,我希望能对很多菜鸟有所帮助。

猜你喜欢

转载自blog.csdn.net/weixin_40480741/article/details/82690771
今日推荐