大家都知道在开发的项目中不可或缺的就是登录模块,在登录模块中当然也少不了需要做登录拦截,因为不做登录拦截的话,如果用户知道某些接口的url地址,就可以跳过登录界面,直接在浏览器上输入接口的url进行访问,直接操作我们的数据,这样肯定是不安全的。所有我们需要做登录拦截,即在用户在不登录的情况下,不管是通过页面访问需要登录的接口,还是直接通过在浏览器上输入url来访问需要登录的接口,都不能让其访问,必须要让其登录之后才能访问到。如果在没有登录的情况下通过任何一种方式来访问需要在登录的情况下才能访问的接口,都会跑出异常
那么以上的问题应该怎么来实现呢?其实很简单,我们只需要用到两个东西就可以了,即HandlerInterceptor 接口和WebMvcConfigurerAdapter类
1、首先创建一个LoginInterceptor类来实现HandlerInterceptor ,这个类是整个登录认证模块中的核心类之一,它实现了HandlerInterceptor类,由它来拦截并过滤到来的每一个请求;它的三个方法能分别作用于每个请求的不同生命周期,你可以根据自己的需要来加入相应的处理逻辑;
@Component
public class LoginInterceptor implements HandlerInterceptor {
/**
* 在请求被处理之前调用
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//在方法中编写拦截的业务代码,返回true就放行,返回false就抛异常。以下的两个方法是一样的。比如我在这里就写了一个拦截的例子
// 检查每个到来的请求对应的session域中是否有登录标识
Object loginName = request.getSession().getAttribute("loginName");
if (null == loginName || !(loginName instanceof String)) {
// 未登录,重定向到登录页
response.sendRedirect("/");
return false;
}
String userName = (String) loginName;
System.out.println("当前用户已登录,登录的用户名为: " + userName);
return true;
}
/**
* 在请求被处理后,视图渲染之前调用
* @param request
* @param response
* @param handler
* @param modelAndView
* @throws Exception
*/
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
}
/**
* 在整个请求结束后调用
* @param request
* @param response
* @param handler
* @param ex
* @throws Exception
*/
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
}
}
2、编写好上面的LoginInterceptor 拦截器后,我们还需要编写一个配置类,LoginConfiguration.java,该类是另一个核心类之一,它继承自WebMvcConfigurerAdapter类,负责注册并生效我们自己定义的拦截器配置;在这里要注意定义好拦截路径和排除拦截的路径;
@Configuration
public class LoginConfiguration implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 注册拦截器
LoginInterceptor loginInterceptor = new LoginInterceptor();
InterceptorRegistration loginRegistry = registry.addInterceptor(loginInterceptor);
// 拦截路径
loginRegistry.addPathPatterns("/**");
// 排除路径
loginRegistry.excludePathPatterns("/");
loginRegistry.excludePathPatterns("/login");
loginRegistry.excludePathPatterns("/loginout");
// 排除资源请求
loginRegistry.excludePathPatterns("/css/login/*.css");
loginRegistry.excludePathPatterns("/js/login/**/*.js");
loginRegistry.excludePathPatterns("/image/login/*.png");
}
将上面的两个类编写好之后,在访问的时候,只要是在配置类中的拦截路径下配置的接口路径,通过都要经过拦截器进行拦截判断,只有通过了我们自己编写的拦截业务后才会被放行,不然的话就会直接抛异常
来源:CSDN
作者:CODE农民
链接:https://blog.csdn.net/heqiang000/article/details/103330478