在服务网关中定义过滤器,只需要继承ZuulFilter抽象类,实现其定义的四个抽象函数,就可对请求进行拦截与过滤

过滤器两个功能:

  1. 路由功能负责将外部请求转发到具体的微服务实例上,是实现外部访问统一入口的基础
  2. 过滤器功能则负责对请求的处理过程进行预干预,是实现请求校验、服务聚合等功能的基础

请求生命周期

  1. pre :在请求路由到目标之前执行。一般用于请求认证、负载均衡和日志记录
  2. route :在路由请求时候被调用,处理目标请求
  3. post :在route和error过滤器之后被调用,一般会在此步骤添加响应头、收集统计和性能数据等
  4. error :处理请求时发生错误时被调用

第一阶段:pre类型的过滤器处理

第二个阶段:routing,路由请求转发阶段
请求将会被routing类型过滤器处理,这里的具体处理内容就是将外部请求转发到具体服务实例上去的过程
当服务实例将请求结果都返回之后,routing阶段完成 第三个阶段:post,此时请求将会被post类型的过滤器进行处理
这些过滤器在处理的时候不仅可以获取到请求信息,还能获取到服务实例的返回信息,
所以在post类型的过滤器中,我们可以对处理结果进行一些加工或转换等内容。 一个特殊的阶段:error,该阶段只有在上述三个阶段中发生异常的时候才会触发
但是它的最后流向还是post类型的过滤器,因为它需要通过post过滤器将最终结果返回给请求客户端

网站前台的token转发(经过网关,头信息会丢失)

@Component
public class WebFilter extends ZuulFilter {
/**
* pre :在请求路由到目标之前执行。一般用于请求认证、负载均衡和日志记录
* route :在路由请求时候被调用,处理目标请求
* post :在route和error过滤器之后被调用,一般会在此步骤添加响应头、收集统计和性能数据等
* error :处理请求时发生错误时被调用
*/
@Override
public String filterType() {
return "pre"; //"pre"代表前置过滤器
} @Override
public int filterOrder() {
return 0; //通过int值来定义过滤器的执行顺序,优先级为0,数字越大,优先级越低
} @Override
public boolean shouldFilter() {
return true; //执行过滤器的条件,开启过滤器
} @Override
public Object run() throws ZuulException { //过滤器的具体逻辑
//向header中添加鉴权令牌
RequestContext requestContext = RequestContext.getCurrentContext();
//获取header
HttpServletRequest request = requestContext.getRequest();
String authorization = request.getHeader("Authorization");
if (authorization != null) {
requestContext.addZuulRequestHeader("Authorization", authorization);
}
return null;
}
}

管理后台过滤器实现token校验

public class WebFilter extends ZuulFilter {

    @Autowired
private JwtUtil jwtUtil; @Override
public String filterType() {
return "pre"; //"pre"代表前置过滤器
} @Override
public int filterOrder() {
return 0; //通过int值来定义过滤器的执行顺序,优先级为0,数字越大,优先级越低
} @Override
public boolean shouldFilter() {
return true; //开启过滤器
} @Override
public Object run() throws ZuulException { //过滤器的具体逻辑
RequestContext requestContext = RequestContext.getCurrentContext();
HttpServletRequest request = requestContext.getRequest(); if (request.getMethod().equals("OPTIONS")) return null; //网关转发内部请求,直接放行
if (request.getRequestURI().indexOf("login") > 0) return null; //登陆放行 String authHeader = request.getHeader("Authorization"); //获取头信息
if (authHeader != null && authHeader.startsWith("Bearer ")) {
String token = authHeader.substring(7); //获取Token
Claims claims = jwtUtil.parseJWT(token); //解析Token
if (claims != null) {
if ("admin".equals(claims.get("roles"))) {
requestContext.addZuulRequestHeader("Authorization", authHeader);
System.out.println("token 验证通过,添加了头信息" + authHeader);
return null;
}
}
} /**
* 通过 requestContext.setSendZuulResponse(false) 令zuul过滤该请求,不对其进行路由
* 通过 requestContext.setResponseStatusCode(403) 设置了其返回的错误码
*/
requestContext.setSendZuulResponse(false); //终止运行
requestContext.setResponseStatusCode(403); //http状态码
requestContext.setResponseBody("权限不足"); requestContext.getResponse().setContentType("text/html;charset=UTF‐8");
return null;
}
}

ZuulFilter的更多相关文章

  1. Spring Cloud Zuul 添加 ZuulFilter

    紧接着上篇随笔Spring Cloud Zuul写,添加过滤器,进行权限验证 1.添加过滤器 package com.dzpykj.filter; import java.io.IOException ...

  2. ZuulFilter 执行顺序

    说明: 创建了两个Filter,分别是 PreFilter public class PreFilter extends ZuulFilter { public PreFilter() { super ...

  3. springcloud zuulfilter 实现get,post请求日志记录功能

    import com.alibaba.fastjson.JSONObject; import com.idoipo.infras.gateway.open.model.InvokeLogModel; ...

  4. springcloud zuul 使用zuulfilter 修改请求路径和响应头

    最近做项目有一个需求:一个网盘系统,文件存放在分布式文件系统中,之前的文件下载统一走的文件下载服务,现在需要在单文件下载的时候不需要走文件下载服务,而是直接访问文件系统上的路径,响应的时候修改响应头, ...

  5. Spring Cloud之ZuulFilter拦截请求参数

    过滤器放到网关: package com.toov5.filter; import javax.servlet.http.HttpServletRequest; import org.apache.c ...

  6. Zuul整合Swagger,使用ZuulFilter解决下游服务context-path

    问题起因:使用Zuul网关服务,需要整合下游系统的swagger,但是下游服务存在context-path配置,无法正确跳转,最后使用ZuulFilter解决. 1.Zuul整合下游swagger 首 ...

  7. 服务网关ZuulFilter过滤器--pre/post/error的用法(校验请求信息,获取路由后的请求/响应信息,处理服务网关异常)

    微服务中Zuul服务网关一共定义了四种类型的过滤器: pre:在请求被路由(转发)之前调用 route:在路由(请求)转发时被调用 error:服务网关发生异常时被调用 post:在路由(转发)请求后 ...

  8. ZuulServlet源码分析及ZuulFilter加载

    参考https://yq.aliyun.com/wenji/2...https://blog.csdn.net/lds2227... 1.声明ZuulServlet @Configuration @E ...

  9. Spring Cloud Zuul之ZuulFilter详解

    简介 Spring Cloud Zuul网关在整个微服务体系中肩负对外开放接口.请求拦截.路由转发等作用,其核心处理则是ZuulFilter ZuulFilter部分源码 Zuul Filter全部继 ...

随机推荐

  1. 13、如何拆分含有多种分隔符的字符串 14、如何判断字符串a是否以字符串b开头或结尾 15、如何调整字符串中文本的格式 16、如何将多个小字符串拼接成一个大的字符串

    13.如何拆分含有多种分隔符的字符串 import re s = "23:41:2314\1234#sdf\23;" print(re.split(r'[#:\;]+',s))   ...

  2. 自动化监控系统(二)连接数据库,创建app,添加model,同步数据库

    数据库我使用:mysql5.7 程序连接数据库的模块:pymysql 一.创建数据库: dbname:automatedmonitor 二.使用pip安装pymysql,这里我直接在pycharm上安 ...

  3. element ui设置表格表头高度和每一行的高度

    填坑记录:今天用element ui的表格组件做用户信息展示,直接拉取的官网的代码过来,发现表头和每一行都太高了,如下: 因为第一次使用element ui的表格组件,不太清楚会遇到这样的坑,以为能轻 ...

  4. etimer

     Contiki包含一个时钟模型和5个定时器模型(timer, stimer, ctimer, etimer, and rtimer),先学习etimer吧. etimer是一个结构体,(个人用eve ...

  5. 如何清除Windows共享登录的用户名密码

    打开cmd 1.[查看已记录的登录信息] net use 2.[清除记录] 得关掉你所有打开的samba之后再 net use * /del

  6. leetcood学习笔记-437-路径总和③**

    题目描述: 方法一:栈 class Solution(object): def pathSum(self, root, sum): """ :type root: Tre ...

  7. delphi 文件存取方法与文件管理组件

    9.2  文件存取方法与文件管理组件 9.2.1  存取文件的类方法 Delphi在许多需要与文件打交道的类中定义了文件存取方法,使用这些方法可以非常方便地将类中的数据保存到文件中,或从文件中读取所需 ...

  8. Ruby 安装 – Unix

    Ruby 安装 - Unix 下面列出了在 Unix 机器上安装 Ruby 的步骤. 注意:在安装之前,请确保您有 root 权限. 下载最新版的 Ruby 压缩文件.请点击这里下载. 下载 Ruby ...

  9. JQuery简单实用的模板引擎

    1.在html界面声明模板(注意type类型) <script id="tmplInvokeProvider" type="text/x-jquery-tmpl&q ...

  10. NX二次开发-UFUN按类选择对话框UF_UI_select_with_class_dialog

    #include <uf.h> #include <uf_ui.h> UF_initialize(); //按类选择对话框 char sCue[] = "按类选择对话 ...