博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java B2B2C Springcloud仿淘宝电子商城系统- Zuul过滤器返回值拦截
阅读量:7174 次
发布时间:2019-06-29

本文共 4257 字,大约阅读时间需要 14 分钟。

Zuul作为网关服务,是其他各服务对外中转站,通过Zuul进行请求转发。这就涉及到部分数据是不能原封返回的,比如服务之间通信的凭证,用户的加密信息等等。

需要JAVA Spring Cloud大型企业分布式微服务云构建的B2B2C电子商务平台源码 一零三八七七四六二六

举个例子,用户服务提供一个登录接口,用户名密码正确后返回一个Token,此Token作为用户服务的通行证,那么用户登录成功后返回的Token就需要进行加密或者防止篡改处理。在到达用户服务其他接口前,就需要对Token进行校验,非法的Token就不需要转发到用户服务中了,直接在网关层返回信息即可。

要修改服务返回的信息,需要使用的是Zuul的过滤器。使用时只需要继承ZuulFilter,实现必要的方法即可。

Zuul提供默认的四种过滤器类型,通过filterType方法进行标识

pre:可以在请求被路由之前调用

route:在路由请求时候被调用

post:在route和error过滤器之后被调用

error:处理请求时发生错误时被调用

过滤器执行的顺序是通过filterOrder方法进行排序,越小的值越优先处理。FilterConstants定义了一些列默认的过滤器的执行顺序和路由类型,大部分需要用到的常量都在这儿。

例子中说明的,只有登录接口需要拦截,所以只需要拦截登录请求(/user/login)即可。可以通过过滤器的shouldFilter方法进行判断是否需要拦截。

由于是在准发用户服务成功后进行的数据修改,所以拦截器的类型时post类型的。整个类的实现如下:

public class AuthResponseFilter extends AbstractZuulFilter {    private static final String RESPONSE_KEY_TOKEN = "token";    @Value("${system.config.authFilter.authUrl}")    private String authUrl;    @Value("${system.config.authFilter.tokenKey}")    private String tokenKey = RESPONSE_KEY_TOKEN;    @Autowired    private AuthApi authApi;    @Override    public boolean shouldFilter() {        RequestContext context = getCurrentContext();        return StringUtils.equals(context.getRequest().getRequestURI().toString(), authUrl);    }    @Override    public Object run() {        try {            RequestContext context = getCurrentContext();            InputStream stream = context.getResponseDataStream();            String body = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));            if (StringUtils.isNotBlank(body)) {                Gson gson = new Gson();                @SuppressWarnings("unchecked")                Map
result = gson.fromJson(body, Map.class); if (StringUtils.isNotBlank(result.get(tokenKey))) { AuthModel authResult = authApi.encodeToken(result.get(tokenKey)); if (authResult.getStatus() != HttpServletResponse.SC_OK) { throw new IllegalArgumentException(authResult.getErrMsg()); } String accessToken = authResult.getToken(); result.put(tokenKey, accessToken); } body = gson.toJson(result); } context.setResponseBody(body); } catch (IOException e) { rethrowRuntimeException(e); } return null; } @Override public String filterType() { return FilterConstants.POST_TYPE; } @Override public int filterOrder() { return FilterConstants.SEND_RESPONSE_FILTER_ORDER - 2; }}复制代码

配置文件,中添加授权url和返回token的key:

system.config.authFilter.authUrl=/user/login system.config.authFilter.tokenKey=token context.setResponseBody(body)复制代码

这段代码是核心,通过此方法修改返回数据。

当用户登录成功后,根据返回的token,通过授权服务进行token加密,这里加密方式使用的是JWT。防止用户篡改信息,非法的请求直接可以拦截在网关层。

关于Zuul过滤器的执行过程,这里不需要多说明,源码一看便知,ZuulServletFilter:

@Override    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {        try {            init((HttpServletRequest) servletRequest, (HttpServletResponse) servletResponse);            try {                preRouting();            } catch (ZuulException e) {                error(e);                postRouting();                return;            }            // Only forward onto to the chain if a zuul response is not being sent            if (!RequestContext.getCurrentContext().sendZuulResponse()) {                filterChain.doFilter(servletRequest, servletResponse);                return;            }            try {                routing();            } catch (ZuulException e) {                error(e);                postRouting();                return;            }            try {                postRouting();            } catch (ZuulException e) {                error(e);                return;            }        } catch (Throwable e) {            error(new ZuulException(e, 500, "UNCAUGHT_EXCEPTION_FROM_FILTER_" + e.getClass().getName()));        } finally {            RequestContext.getCurrentContext().unset();        }    }复制代码

方法说明:

preRoute:执行pre类型的过滤器

postRoute:执行post类型的过滤器

route:执行route类型的过滤器

error:执行error类型的过滤器

通过context.setSendZuulResponse(false)可以终止请求的转发,但是只在pre类型的过滤器中设置才可以。

转载地址:http://jrbzm.baihongyu.com/

你可能感兴趣的文章
ubuntu 查看进程,查看服务
查看>>
Cisco DHCP Snooping + IPSG 功能实现
查看>>
Linux命令_用户身份切换
查看>>
学习在.NET Core中使用RabbitMQ之启动和基础(一)
查看>>
支付业务的数据库表的设计
查看>>
php面试题二--解决网站大流量高并发方案(从url到硬盘来解决高并发方案总结)...
查看>>
PHP 16 个编程法则
查看>>
【微信】2.微信小程序开发--官方开发工具使用说明
查看>>
RedisTemplate访问Redis数据结构
查看>>
面试如何回答优化数据库
查看>>
SuperSocket与Netty之实现protobuf协议,包括服务端和客户端
查看>>
ASP.NET CORE系列【二】使用Entity Framework Core进行增删改查
查看>>
AIDL基本使用
查看>>
MySQL中间件之ProxySQL(6):管理后端节点
查看>>
Mathematica 取整函数
查看>>
(转)Awsome Domain-Adaptation
查看>>
利用cwRsync客户端将Windows下文件同步到Linux
查看>>
npm常用命令
查看>>
String,StringBuffer和StringBuilder三者的讲解
查看>>
Understanding Digital Raw Capture
查看>>