简易拦截器(备忘)

此拦截器代码用于本人备忘,若有错误需要修改的地方,请大家指正,谢谢!

package com.shirt.interceptor;

import com.shirt.constants.Constants;
import com.shirt.model.UserModel;
import com.shirt.service.AuthService;
import com.shirt.utils.JsonUtil;
import com.shirt.utils.Result;
import com.shirt.utils.SysUtil;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.PrintWriter;
import java.util.List;

public class LoginInterceptor implements HandlerInterceptor {

	private Logger log = LoggerFactory.getLogger(getClass());

	//允许跨域的Url(系统未做拦截,允许所有url跨域访问)
	private List<String> originUrls;
	//不拦截的URL
	private List<String> exceptUrls;
	//以*开头的URL不拦截
	private List<String> startUrls;
	//以*结尾的URL不拦截
	private List<String> endUrls;

	@Resource
	private AuthService authService;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
		//获取访问路径
		String url = request.getRequestURI();
		//不需要拦截的页面直接通过拦截
		if (isIgnore(url)){
			return true;
		}
		if(request.getMethod().equals("OPTIONS")){
			return true;
		}
		//获取访问者Origin,允许跨域访问
		String originUrl = request.getHeader("Origin");
		//如需要限制跨域ip,需自行配置originUrls
		/*String originHeader=request.getHeader("Origin");
		if (originUrls.contains(originHeader)){
			originUrl = originHeader;
		}*/
		//获取token校验用户是否登陆
		String token = SysUtil.getTokenFromRequestHeader();
		response.setContentType("application/json");// 设置响应的内容类型属性为json字符串
		response.setHeader("Access-Control-Allow-origin", originUrl);// 设置允许浏览器跨域访问的属性
		response.setHeader("Access-Control-Allow-Credentials", "true");
		response.setHeader("Access-Control-Allow-Methods", "*");
		response.setHeader("Access-Control-Allow-Headers", "Authentication,Origin, X-Requested-With, Content-Type, Accept,token");
		if (StringUtils.isBlank(token)) {// 如果本次访问的header属性中没有登录凭证(token)参数
			PrintWriter out = response.getWriter();// 从响应实体类对象中获取输出流
			out.write(JsonUtil.objToJson(new Result(Constants.LOGIN_CODE.UN_AUTHORIZED, "没有登录授权,拒绝本次请求")).toString());// 把要返回给请求端的业务状态码和相关信息写入输出流
			out.flush();// 释空输出流缓冲区
			log.info("接口[" + url + "]调用请求的header信息中缺少token参数");// 记录业务日志
			return false;// 拦截校验没有通过
		}
		Result resultCode = authService.checkToken(token);// 对header中携带的登录凭证参数(token)进行校验
		if (!Constants.RESULT_CODE.SUCCESS.equals(resultCode.getReturnCode())) {// 如果获取到的登录凭证经检测已经过期失效
			PrintWriter out = response.getWriter();// 从响应实体类对象中获取输出流
			out.write(JsonUtil.objToJson(resultCode).toString());// 把要返回给请求端的业务状态码和相关信息写入输出流
			out.flush();// 释空输出流缓冲区
			log.error("接口[" + url + "]调用请求所携带的的token[" + token + "]已经过期");// 记录业务日志
			return false;// 拦截校验没有通过
		}
		// 权限认证
		if (resultCode.getReturnData()==null||!checkAuthByUser((UserModel)resultCode.getReturnData(),url)) {
			log.error("接口[" + url + "]调用请求所携带的的token[" + token + "]权限不足");// 记录业务日志
			PrintWriter out = response.getWriter();// 从响应实体类对象中获取输出流
			out.write(JsonUtil.objToJson(new Result(Constants.LOGIN_CODE.UN_AUTHORIZED, "权限不足")).toString());// 把要返回给请求端的业务状态码和相关信息写入输出流
			out.flush();// 释空输出流缓冲区
			return false;
		}
		return true;// 通过拦截校验
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
                           ModelAndView modelAndView) throws Exception {
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
	}
	/**
	 * 判断请求路径是否需要拦截
	 * @return
	 */
	private boolean isIgnore(String url){
		if (StringUtils.isNotBlank(url)) {
			//默认访问路径不拦截
			if ("/".equals(url)){
				return true;
			}
			//不拦截的路径
			for (String ignoreUrl : exceptUrls) {
				if (url.equalsIgnoreCase(ignoreUrl)) {
					return true;
				}
			}
			//以**开头的路径不拦截
			for (String ignoreUrl : startUrls) {
				if (url.startsWith(ignoreUrl)) {
					return true;
				}
			}
			//以**结尾的路径不拦截
			for (String ignoreUrl : endUrls) {
				if (url.endsWith(ignoreUrl)) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * 校验用户是否拥有访问权限
	 * @param userModel
	 * @param url
	 * @return
	 */
	private boolean checkAuthByUser(UserModel userModel, String url){
		//用户有权访问的菜单
		/*for (Menu menu : userModel.getMenus()) {
			if (url.equals(menu.getFile()))
				return true;
		}
		return false;*/
		return true;
	}

	public List<String> getExceptUrls() {
		return exceptUrls;
	}

	public void setExceptUrls(List<String> exceptUrls) {
		this.exceptUrls = exceptUrls;
	}

	public List<String> getStartUrls() {
		return startUrls;
	}

	public void setStartUrls(List<String> startUrls) {
		this.startUrls = startUrls;
	}

	public List<String> getEndUrls() {
		return endUrls;
	}

	public void setEndUrls(List<String> endUrls) {
		this.endUrls = endUrls;
	}

	public List<String> getOriginUrls() {
		return originUrls;
	}

	public void setOriginUrls(List<String> originUrls) {
		this.originUrls = originUrls;
	}
}
<!--拦截器配置 -->
	<mvc:interceptors>
		<mvc:interceptor>
			<mvc:mapping path="/**" />
			<bean class="com.shirt.interceptor.LoginInterceptor">
				<property name="exceptUrls">
					<list>
						<value>/login</value>
						<value>/login/out</value>
					</list>
				</property>
				<property name="endUrls">
					<list>
						<value>.jsp</value>
						<value>.js</value>
						<value>.css</value>
						<value>/error</value>
					</list>
				</property>
				<property name="startUrls">
					<list>
						<value>/WEB-INF/js/</value>
						<value>/WEB-INF/css/</value>
						<value>/WEB-INF/jsp/</value>
					</list>
				</property>
				<property name="originUrls">
					<list>
						<!--<value>http://localhost:8080</value>-->
					</list>
				</property>
			</bean>
		</mvc:interceptor>
	</mvc:interceptors>

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值