龙空技术网

【框架篇】统一用户登录权限验证

智者远行惠通天下 322

前言:

现时咱们对“权限管理系统权限设置”都比较看重,姐妹们都需要了解一些“权限管理系统权限设置”的相关资讯。那么小编也在网摘上网罗了一些对于“权限管理系统权限设置””的相关资讯,希望兄弟们能喜欢,姐妹们一起来学习一下吧!

统一用户登录权限验证

1,自定义拦截器

对于统一用户登录权限验证的问题,Spring中提供了具体的解决方法,该方法为设置拦截器:HandlerInterceptor。

自定义拦截器的实现分为以下两个步骤:

创建自定义拦截器类,实现HandlerInterceptor接口,并重写preHandle方法,该方法在处理具体方法之前进行预处理。

将⾃定义拦截器配置到系统配置项,并且设置合理的拦截规则。实现 WebMvcConfigurer 的 addInterceptors ⽅法。

自定义拦截器创建

// 自定义拦截器创建

public class LoginInterceptor implements HandlerInterceptor {

@Override

public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

HttpSession session = request.getSession(false);

if(session!=null && session.getAttribute("session_userinfo")!=null){

return true;

}

response.setStatus(401);

return false;

}

}

自定义拦截器创建的实现代码解释:

1,创建自定义拦截器类,实现HandlerInterceptor接口,并重写preHandle方法,该方法在处理具体方法之前进行预处理。

2,preHandle方法的返回结果为t布尔类型的数据,当返回的数据为true时,表示拦截器验证成功,继续执行后续的操作流程,而当返回的结果为false时,表示拦截器验证失败,后续的操作流程就不再执行。

将⾃定义拦截器配置到系统配置项,并且设置合理的拦截规则

@Configuration

public class MyConfiguration implements WebMvcConfigurer {

@Resource

private LoginInterceptor loginInterceptor;

@Override

public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(loginInterceptor)

.addPathPatterns("/**") // 拦截所有的url

.excludePathPatterns("/login"); // 排除名为login的url

}

}

实现代码解释:

1,创建一个配置类(可使用@Configuration注解),实现WebMvcConfigurer接口,并重写addInterceptors方法。

2,registry为注册器,通过调用addInterceptor方法将自定义拦截器添加到系统配置项中。

3,将自定义拦截器添加到系统配置项中有两种写法,分别为:

通过new方式添加:registry.addInterceptor(new LoginInterceptor())

通过依赖注入方式添加:registry.addInterceptor(loginInterceptor)

4,addPathPatterns方法设置需要拦截的URL路径,可使用通配符进行匹配;excludePathPatterns方法设置需要排除的URL路径。

/**匹配所有的url路径,/*匹配一级的url路径

2,拦截器的实现原理

正常情况下业务的执行流程:用户或前端程序将请求发送到后端程序的控制器层Controller,经过控制器层Controller的参数校验操作之后,控制器层Controller根据业务代码的逻辑进行调用对应的服务层Service,然后服务层Service进行调用对应的数据持久层Mapper,数据持久层Mapper进而调用相对应的数据库,数据库将对应操作的数据依次返回给数据持久层Mapper,服务层Service,控制器层Controller,最后把数据返回给前端程序或者用户。

所有的 Controller 执⾏都会通过⼀个调度器 DispatcherServlet 来实现,这⼀点可以从 Spring Boot 控制台的打印信息看出,如下图所示:

而所有的方法都会执行 DispatcherServlet 中的 doDispatch 调度方法,doDispatch 源码如下:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {

HttpServletRequest processedRequest = request;

HandlerExecutionChain mappedHandler = null;

boolean multipartRequestParsed = false;

...

// 检查是否为multipart/*类型

processedRequest = checkMultipart(request);

multipartRequestParsed = (processedRequest != request);

if (mappedHandler == null) {

noHandlerFound(processedRequest, response);

return;

}

// 确认支持当前请求Handler的Adapter,用于调用Handler的handle方法

HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// 处理last-modified请求头

String method = request.getMethod();

boolean isGet = "GET".equals(method);

if (isGet || "HEAD".equals(method)) {

long lastModified = ha.getLastModified(request, mappedHandler.getHandler());

if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {

return;

}

}

// 对拦截器链preHandle的调用

if (!mappedHandler.applyPreHandle(processedRequest, response)) {

return;

}

// HandlerAdapter代理执行Handler的handle方法

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

...

//进行视图的渲染

applyDefaultViewName(processedRequest, mv);

//调用拦截器链的postHandle方法

mappedHandler.applyPostHandle(processedRequest, response, mv);

...

}

从上述源码可以看出在开始执行 Controller 之前,会先调用预处理方法 applyPreHandle。

applyPreHandle 方法的具体实现源码如下:

boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {

HandlerInterceptor[] interceptors = this.getInterceptors();

if (!ObjectUtils.isEmpty(interceptors)) {

for(int i = 0; i < interceptors.length; this.interceptorIndex = i++) {

//拦截器的preHandle方法返回true的时候顺带记录索引

HandlerInterceptor interceptor = interceptors[i];

if (!interceptor.preHandle(request, response, this.handler)) {

//一旦有个前置处理器没放行, 执行拦截器的afterCompletion方法

this.triggerAfterCompletion(request, response, (Exception)null);

return false;

}

}

}

return true;

}

从上述源码可以看出,在 applyPreHandle 中会获取所有的拦截器 HandlerInterceptor 并执行拦截器中的 preHandle 方法,这样就会咱们前⾯定义的拦截器对应上了。

标签: #权限管理系统权限设置