feign拦截器
概述
有的时候业务场景是不走正常路线的,业务场景千奇百怪的需求都有, 有的时候权限校验需要在网关那里统一鉴权,有的时候就需要下放到某个微服务去处理(不在网关那里统一鉴权)
通常我们调用的接口都是有权限控制的,很多时候可能认证的值是通过参数去传递的,还有就是通过请求头去传递认证信息,比如 Basic 认证方式。 接口鉴权
Feign 中我们可以直接配置 Basic 认证
@Configuration // 全局配置public class FeignConfig {@Beanpublic BasicAuthRequestInterceptor basicAuthRequestInterceptor() {retu new BasicAuthRequestInterceptor("fox", "123456");}}
**扩展点: feign.RequestInterceptor **
每次 feign 发起http调用之前,会去执行拦截器中的逻辑。
public interface RequestInterceptor {/*** Called for every request. Add data using methods on the supplied {@link RequestTemplate}.*/ void apply(RequestTemplate template);}
使用场景
- 统一添加 header 信息;
- 对 body 中的信息做修改或替换;
自定义拦截器实现认证逻辑
FeignConfig
package feigndemo.config;import feigndemo.interceptor.FeignAuthRequestInterceptor;import feign.Logger;import feign.Request;import feign.codec.Decoder;import feign.codec.Encoder;import feign.jackson.JacksonDecoder;import feign.jackson.JacksonEncoder;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration; @Configuration // 全局配置public class FeignConfig { /** * 日志级别 * 通过源码可以看到日志等级有 4 种,分别是: * NONE:不输出日志。 * BASIC:只输出请求方法的 URL 和响应的状态码以及接口执行的时间。 * HEADERS:将 BASIC 信息和请求头信息输出。 * FULL:输出完整的请求信息。 */ @Bean public Logger.Level feignLoggerLevel() { retu Logger.Level.FULL; }/** * 自定义拦截器 * @retu */@Beanpublic FeignAuthRequestInterceptor feignAuthRequestInterceptor(){retu new FeignAuthRequestInterceptor();}@Beanpublic Request.Options options() {retu new Request.Options(5000, 5000);}@Beanpublic Decoder decoder() {retu new JacksonDecoder();}@Beanpublic Encoder encoder() {retu new JacksonEncoder();}}
FeignAuthRequestInterceptor
package feigndemo.interceptor;import feign.RequestInterceptor;import feign.RequestTemplate;import java.util.UUID;public class FeignAuthRequestInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {// 业务逻辑 模拟认证逻辑// 请求头携带tokenString access_token = "IAmToken"+UUID.randomUUID().toString();template.header("Authorization",access_token);}}
这样在feign远程调用的时候自动将Authorization携带到header里面了,然后服务的被调用方就可以从header里面获取这个信息了
feign输出:
2022-01-13 12:18:04.322 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] ---> GET http://mall-order/order/findOrderByUserId/1 HTTP/1.12022-01-13 12:18:04.323 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] Authorization: IAmToken53ce45ea-dc4f-4908-9492-e4f6ac43c1c22022-01-13 12:18:04.323 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] ---> END HTTP (0-byte body)2022-01-13 12:18:04.640 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] <--- HTTP/1.1 200 (314ms)2022-01-13 12:18:04.640 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] connection: keep-alive2022-01-13 12:18:04.640 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] content-type: application/json2022-01-13 12:18:04.641 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] date: Thu, 13 Jan 2022 04:18:04 GMT2022-01-13 12:18:04.641 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] keep-alive: timeout=602022-01-13 12:18:04.641 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] transfer-encoding: chunked2022-01-13 12:18:04.641 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] 2022-01-13 12:18:04.641 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] {"msg":"success","code":0,"orders":[{"id":1,"userId":"1","commodityCode":"1","count":1,"amount":1}]}2022-01-13 12:18:04.641 DEBUG 79432 --- [nio-8055-exec-1] feigndemo.feign.OrderFeignService: [OrderFeignService#findOrderByUserId] <--- END HTTP (100-byte body)
服务提供者拦截器
当消费者调用这个服务提供者的时候,拦截器就可以在这里获取到header的token信息了.
@Slf4jpublic class AuthInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {boolean flag = true;// 简单的认证逻辑 从请求头中获取AuthorizationString authorization = request.getHeader("Authorization");log.info("=========Authorization:"+authorization);if (StringUtils.isEmpty(authorization)){// 从请求参数中获取access_tokenString access_token = request.getParameter("access_token");if(StringUtils.isEmpty(access_token)){flag = false;}}retu flag;}}
代码地址
代码出自图灵学院, 我自己学完了做完作业又改造了一下.
https://gitee.com/zjj19941/ZJJ_Neaten5.10/tree/master/ZJJ_Feign/feign-interceptor
先执行sql脚本,自己准备一个nacos服务,然后修改配置文件配置,
最后,启动 com.order.MallOrderApplication 和 feigndemo.MallUserFeignDemoApplication
然后postman发起get请求: localhost:8055/user/findOrderByUserId/1
就能看到效果了
补充:可以在yml中配置
feign: client:config: mall-order: #对应微服务requestInterceptors[0]: #配置拦截器 feigndemo.interceptor.FeignAuthRequestInterceptor
作者:张俊杰1994
来源链接:https://blog.csdn.net/qq_41489540/article/details/122471338
版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。
2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。