SpringMVC拦截器实现登录认证(2017修正版)

     当使用到springmvc的做网页工程的时候,总会遇到需要判断登陆权限的,一般的做法是每次登陆的话,发送给后台,后台返回一个唯一的token,以便标识用户每一次请求的权限,如果没有登陆成功,则token为空,访问任意网址都会跳到登陆界面,所以网上查了,有很多博客说了,例如这位前辈:http://blog.csdn.net/u014427391/article/details/51419521,我的基本代码都是参考它的。

      注意: 不过我发现了网上所有的登陆权限认证,都忽略了一个问题,如果你的项目中有js/css等其他代码的话,是会都拦截到,就会一直陷入死循环中,导致无法进入主界面,需要把这些js和css等界面的所需的文件,也进行判断才能顺利拦截。(还有访问登陆界面的路径、点击登陆按钮访问后台的路径,都需要判断),其他的路径的话,如果没有token就返回主界面:

            


       所以拦截器需要按照如下方式写,代码如下:(具体拦截那些路径,可以根据自己项目的js/css/image资源的路径配置)

package com.rmsClient.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.rmsClient.util.Constants;

/**
 * 登陆权限:拦截器
 * 
 * @author qiulinhe
 *
 *         2017年1月18日 下午2:40:36
 */
public class LoginInterceptor implements HandlerInterceptor {

	/**
	 * Handler执行之前调用这个方法
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// 获取请求的URL
		String url = request.getRequestURI();

		// 注意:一些静态文件不能拦截,否则会死循环,知道内存耗尽
		// URL:login.jsp是公开的;这个demo是除了login.jsp是可以公开访问的,其它的URL都进行拦截控制
		// /RMSClient/WEB-INF/view/register/login.html
		// 地址为/RMSClient/media/js/lib/jquery-1.7.2.min.js
		// 地址为/RMSClient/media/css/base.css
		// 地址为/RMSClient/media/css/login.css
		// 地址为/RMSClient/media/js/lib/html5shiv.js
		// 地址为/RMSClient/media/js/server/login.js
		if (url.indexOf("/RMSClient/login") >= 0 || url.indexOf("/register/login.html") > 0
				|| url.indexOf("/media") > 0 || url.indexOf("/user/login") > 0) {
			return true;
		}
		// 获取Session,判断是否能拿到token,如果没有的话,就需要跳转到主界面
		HttpSession session = request.getSession();

		String token = (String) session.getAttribute(Constants.TOKEN);
		System.out.println("得到的token为:" + token);
		if (token != null) {
			return true;
		}
		// 不符合条件的,跳转到登录界面
		request.getRequestDispatcher("/WEB-INF/view/register/login.html").forward(request, response);

		// response.sendRedirect("/WEB-INF/view/register/login.html");

		return false;
	}

	/**
	 * Handler执行完成之后调用这个方法
	 */
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exc)
			throws Exception {

	}

	/**
	 * Handler执行之后,ModelAndView返回之前调用这个方法
	 */
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	}

}

            其他的需要配置spring.xml里面:

       

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-4.3.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context.xsd 
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx.xsd
          http://www.springframework.org/schema/mvc
       http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!-- 配置扫描的包 -->
    <context:component-scan base-package="com.rmsClient.*" />

    <!-- 注册HandlerMapper、HandlerAdapter两个映射类 -->
    <mvc:annotation-driven />

    <!-- 访问静态资源 -->
    <mvc:default-servlet-handler />
    
    <!-- 视图解析器 -->
    <bean
        class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/view/"></property>
        <property name="suffix" value=".html"></property>
    </bean>
    
    <!-- 拦截器 -->
  <mvc:interceptors>
	<!-- 多个拦截器,顺序执行 -->
	<mvc:interceptor>
		<mvc:mapping path="/**" />
		<!-- 登陆权限拦截器 -->
		<bean class="com.rmsClient.interceptor.LoginInterceptor"></bean>
	</mvc:interceptor>
  </mvc:interceptors> 
    

</beans>

           自此就完成了登陆的验证,希望后人少走弯路,还有网上的博客前辈们总结的很好,不过还是需要自己摸索和实践才行。


===========================分割线,2017年3月2日13:30:35====================

          上述的拦截有一个问题是,如果没有登录权限的,跳转到登陆界面,我是直接访问login.html的文件,浏览器的地址并没有更换成登陆的@RequestMapping(value = "/login"地址,所以需要重定向来解决,如下代码修改一下:

package com.rmsClient.interceptor;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.rmsClient.util.Constants;
import com.rmsClient.util.LogUtil;

/**
 * 登陆权限:拦截器
 * 
 * @author qiulinhe
 *
 *         2017年1月18日 下午2:40:36
 */
public class LoginInterceptor implements HandlerInterceptor {

	/**
	 * Handler执行之前调用这个方法
	 */
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		// 获取请求的URL
		String url = request.getRequestURI();

		// 获取Session,判断是否能拿到token,如果没有的话,就需要跳转到主界面
		HttpSession session = request.getSession();
		String token = (String) session.getAttribute(Constants.TOKEN);

		// swagger的路径也不需要拦截
		// 注意:一些静态文件不能拦截,否则会死循环,知道内存耗尽
		// URL:login.jsp是公开的;这个demo是除了login.jsp是可以公开访问的,其它的URL都进行拦截控制
		// /RMSClient/WEB-INF/view/register/login.html
		// 地址为/RMSClient/media/js/lib/jquery-1.7.2.min.js
		// 地址为/RMSClient/media/css/base.css
		// 地址为/RMSClient/media/css/login.css
		// 地址为/RMSClient/media/js/lib/html5shiv.js
		// 地址为/RMSClient/media/js/server/login.js
		if (url.indexOf("/RMSClient/login") >= 0 || url.indexOf("/RMSClient/useradmin/login") >= 0
				|| url.indexOf("/register/login.html") >= 0 || url.indexOf("/swagger") >= 0
				|| url.indexOf("/media") >= 0 || url.indexOf("/user/login") >= 0
				|| url.indexOf("/RMSClient/WEB-INF/view/") >= 0 || url.indexOf("/RMSClient/view/") >= 0
				|| url.indexOf("/RMSClient/index") >= 0) {

			return true;
		} else if (url.indexOf("/RMSClient/main") >= 0) {
			if (token != null) {
				return true;

			} else {
				// 不符合条件的,跳转到登录界面
				LogUtil.error("没有登陆权限,跳转到登陆界面");
				response.sendRedirect(request.getContextPath() + "/login");//这是非常重要的重定向,需要加上全部路径

				return false;
			}
		}

		if (token != null) {
			return true;

		}

		// 不符合条件的,跳转到登录界面
		LogUtil.error("没有登陆权限,跳转到登陆界面");
		// request.getRequestDispatcher("/WEB-INF/view/user/login.html").forward(request,
		// response);

		response.sendRedirect(request.getContextPath() + "/login");

		return false;
	}

	/**
	 * Handler执行完成之后调用这个方法
	 */
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception exc)
			throws Exception {

	}

	/**
	 * Handler执行之后,ModelAndView返回之前调用这个方法
	 */
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
	}

}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值