方法一,@RequestHeader

在请求调用方的微服务方法头中添加@RequestHeader用来接收用户端请求时传入的token,关键代码片段

@GetMapping(value = "/{id}", produces = MediaType.APPLICATION_JSON_VALUE)
public ShareDTO findById(HttpServletRequest request,
                         @PathVariable Integer id,
                         @RequestParam(name = "foo") String foo,
                         @RequestHeader("X-Token") String token) {
    System.out.println(foo);
    return this.shareService.findById(id, token);
}

这里获取到header中的“X-Token”

在采用Feign调用其他微服务时将获取到的Token传入到下一个微服务的请求头中

@GetMapping("/users/{id}")
UserDTO findById(@PathVariable Integer id, @RequestHeader("X-Token") String token);

这里的@RequestHeader的意思是将参数token放入到下个请求的请求头header中。到此,使用这种方式进行token传递就可以实现了。

方法2 使用Feign的Interceptor

Step1 实现RequestInterceptor接口

apply->获取到X-Token

Step2 将token传递给下一次请求

实现一个RequestInterceptor

实现内容如下

//省略包名
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.apache.commons.lang3.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;

/**
 * @author frend
 * @version v0.0.1
 * @apiNote feign传递token拦截统一处理
 * @time 2020/10/26 12:48
 * @parjectName rate-content-center
 */
public class TokenTelayRequestIntecepor implements RequestInterceptor {

    @Override
    public void apply(RequestTemplate requestTemplate) {
        // 从header获取X-token
        RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
        ServletRequestAttributes srat = (ServletRequestAttributes) requestAttributes;
        HttpServletRequest request = srat.getRequest();
        String token = request.getHeader("X-Token");
        if (StringUtils.isNotBlank(token)) {
            //将token传递出去
            requestTemplate.header("X-Token", token);
        }
    }
}

这里先获取到HTTPServletRequest

接着在从request中获取到header的“X-Token”

将这个token传递给requestTemplate

Interceptor实现之后还需要对这个Interceptor设置配置

Step3 配置Feign

给全局配置一个 requestInterceptors: 将上面的实现了RequestInterceptor的类全路径给这个配置

feign:
  client:
    config:
      default:
        loggerLevel: full
        requestInterceptors:
          - org.rate.contentcenter.feignclients.interceptor.TokenTelayRequestIntecepor

到此,全局的FeignToken传递就实现完成了。

最后做个总结:

1.使用@RequestHeader的方式比较直观,也较为容易理解,但是当对接口进行改造,或者服务接口过多时,任务量巨大

2.使用RequestInterceptor拦截器,在理解上有一些抽象,不过这种方式在实际操作和代码的耦合上是非常有优势的。


 

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐