1.前言
- 我的上一篇博客写了使用拦截器来去检查登录的状态然后给用户显示不同的界面,但是这样还是有问题,虽然用户看不见哪些信息,但是如果我们知道访问路径,照样可以访问到我们没登录时看不到的界面,那么这样就有大问题了,因为,很有可能会有人能通过这些界面影响我们的数据库,这样的话就带来了安全隐患。文字可能不太清楚,上图就明白了。
- 如下图所示,是我们没登录时看到的界面
- 但是我们可以通过更改路径访问到我们的个人中心
- 如下图
- 这就很诡异了,明明我们就没有这个按钮,怎么还能访问到?因此我们要想办法解决这个问题
2.使用拦截器
- 在方法前标注自定义注解
- 拦截所有的请求,只处理带有该注解的方法
2.1.自定义注解
- 常用的元注解
- @Target,声明自定义的注解可以写在哪个位置,可以作用在哪些类型上(类,方法,属性…)
- @Retention,声明注解保留的时间,是编译时有效还是运行时有效
- @Document,声明我们在生成文档时,要不要也把注解带上去
- @Inherited,用于继承的,子类继承父类,要不要把注解也继承过来
- 如何读取注解?通过反射
- Method.getDeclaredAnnotations(),获取这个方法上所有的注解
- Method.getAnnotation(class, annotationClass),获取某个类型的注解
3.编写注解类
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LoginRequired {
}
4.拦截未登录时的请求
5.编写拦截器类
@Component
public class LoginRequiredInterceptor implements HandlerInterceptor {
@Autowired
private HostHolder hostHolder;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if(handler instanceof HandlerMethod){
HandlerMethod handlerMethod = (HandlerMethod) handler;
Method method = handlerMethod.getMethod();
LoginRequired loginRequired = method.getAnnotation(LoginRequired.class);
if(loginRequired != null && hostHolder.getUser() == null){
response.sendRedirect(request.getContextPath() + "/login");
return false;
}
}
return true;
}
}
6.配置config类,不拦截静态资源
registry.addInterceptor(loginRequiredInterceptor)
.excludePathPatterns("/**/*.css", "/**/*.js", "/**/*.png", "/**/*.jpg", "/**/*.jpeg");
7.运行结果
- 我们再访问之前的路径,未登录时就会直接跳转到登录页面了,就不能让他访问到了。