此拦截器代码用于本人备忘,若有错误需要修改的地方,请大家指正,谢谢!
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>