服务对外提供接口以供不同站点之间使用:Spring Cloud Feign使用记录及携带token请求

摘要:
但最方便和优雅的方式是通过SpringCloudOpenFeign调用服务。Spring Cloud增强了Feign,使Feign支持Spring Mvc注释,并集成ribbon等,使Fegn更方便使用。SpringCloud集成Ribbon和Eureka,在使用Feign时提供负载平衡的http客户端。Feign函数:它可以解决不同服务器接口之间的相互调用,即跨域请求!如何在跨域请求中放置令牌?

  在开发 Spring Cloud 微服务的时候,我们知道,服务之间都是以 HTTP 接口的形式对外提供服务的,因此消费者在进行调用的时候,底层就是通过 HTTP Client 的这种方式进行访问。当然我们可以使用JDK原生的 URLConnection、Apache 的 HTTP Client、Netty 异步 Http Client,Spring 的 RestTemplate 去实现服务间的调用。但是最方便、最优雅的方式是通过 Spring Cloud Open Feign 进行服务间的调用。Spring Cloud 对 Feign 进行了增强,使 Feign 支持 Spring Mvc 的注解,并整合了 Ribbon 等,从而让 Feign 的使用更加方便。

  Feign是一个声明式的Web服务客户端,使用Feign可使得Web服务客户端的写入更加方便。 它具有可插拔注释支持,包括Feign注解和JAX-RS注解、Feign还支持可插拔编码器和解码器、Spring Cloud增加了对Spring MVC注释的支持,并HttpMessageConverters在Spring Web中使用了默认使用的相同方式。Spring Cloud集成了Ribbon和Eureka,在使用Feign时提供负载平衡的http客户端。

  Feign作用:可以解决不同服务器接口之间的相互调用,即跨域请求!feign结合eureka注册中心,把不同的服务项目注册到eureka中,通过feign客户端进行调用,可以解决负载均衡问题。

  接下来就简单讲述一下Feign的入门使用

一、引入依赖及配置编写

1、引入依赖

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-gson</artifactId>
    <version>10.2.3</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.1.1.RELEASE</version>
</dependency>

2、编写配置文件

@Configuration
public class FeignConfiguration {

    @Bean
    public Contract feignContract() {
        return new Contract.Default();
    }

    @Bean
    Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL;
    }

    @Bean
    Decoder feignDecoder() {
        return new GsonDecoder();
    }

    @Bean
    Encoder feignEncoder() {
        return new GsonEncoder();
    }
}

3、在应用主类Application里,通过@EnableFeignClients注解开启Spring Cloud Feign的支持功能。

// 在启动类上加上注解
// 开启 Feign 扫描支持
@EnableFeignClients

二、编写Feign接口及使用

1、编写Feign接口

  @FeignClient注解指定服务名来绑定服务,然后再使用Spring MVC的注解来绑定具体该服务提供的REST接口。

@FeignClient(name = "myApi", url = "http://localhost:8080")
public interface MyService {
    // 调用另外一个服务的接口
    @RequestLine("GET /getUsers?searchString={searchString}")
    @Headers("Content-Type: application/json")
    List<User> getUsers(@Param("searchString") String searchString);
}

2、使用接口

  Feign接口不需要实现类,可直接调用

    private MyService myService;

    @GetMapping("/userList")
    public List<User> getUsers(@RequestParam String searchString){
        List<User> userList = myService.getUsers(searchString);
        return userList;
    }

三、携带token请求

  为了安全考虑要访问的服务的接口需要token验证才能访问,因此需要携带token才能访问。关于新的服务搭建安全框架,使用与要访问的平台一致的token生成和验证机制,这里就不赘述了。

1、方案一:直接在@Headers注解中加token

  这种方案可以用来测试,因为,这种方式token是写死的,不能根据浏览器携带的token进行验证。

@FeignClient(name = "myApi", url = "http://localhost:8080")
public interface MyService {
    @RequestLine("GET /getUsers?searchString={searchString}")
    // 直接在@Headers注解中加token
    @Headers({"Content-Type: application/json", "Authorization: Bearer eyJh..."})
    List<User> getUsers(@Param("searchString") String searchString);
}

2、方案二:根据浏览器动态获取token

如何从浏览器中拿到token?

服务对外提供接口以供不同站点之间使用:Spring Cloud Feign使用记录及携带token请求第1张

  可以看到javax.servlet.http包下有个getHeader的方法,可以获得当前浏览器Header中的信息。

如何将token放到跨域请求中?

服务对外提供接口以供不同站点之间使用:Spring Cloud Feign使用记录及携带token请求第2张

  在fegin包中的请求拦截器RequestInterceptor有个apply方法,该方法的默认实现如下:

服务对外提供接口以供不同站点之间使用:Spring Cloud Feign使用记录及携带token请求第3张

  可以看到,默认的Authorization是通过用户名和密码进行base64加密得到的,跟我们的token生成方式不一样,所以直接使用默认的是无法验证通过的,因此,只需实现RequestInterceptor,重写apply方法即可

解决方案

  编写配置类,实现RequestInterceptor,重写apply方法,把浏览器header拿到的token放进去。

@Slf4j
@Configuration
@AllArgsConstructor
public class NimBusRequestInterceptor implements RequestInterceptor {

    private HttpServletRequest req;
    private static final String HEADER_STRING = "Authorization";

    @Override
    public void apply(RequestTemplate requestTemplate) {
        // 如果header没有auth头,从cookie获取token
        String token = req.getHeader(HEADER_STRING);
        Cookie[] cookies = req.getCookies();
        if (cookies != null && cookies.length > 0) {
            for (Cookie cookie : cookies) {
                if (Objects.equals(cookie.getName(), "token")) {
                    try {
                        token = URLDecoder.decode(cookie.getValue(), StandardCharsets.UTF_8.name());
                    } catch (UnsupportedEncodingException e) {
                        log.error(LogUtil.getStack(e));
                    }
                }
            }
        }
        requestTemplate.header(HEADER_STRING, token);
    }
}

  以上就实现了Feign基本使用与携带token请求。

免责声明:文章转载自《服务对外提供接口以供不同站点之间使用:Spring Cloud Feign使用记录及携带token请求》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇MYSQL触发器的使用.NetCore快速上手Consul,留给自己一点思考的空间下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

接口测试笔记

1.2 一..接口测试:通过相应的工具或者人工对某一个接口的工作状态进行测试的过程 二..接口测试点: 1.测试接口正确性:保证接口地址与请求方法是正确的 2.测试接口的安全性:有一些接口不能直接暴露,我们需要对它进行炎症之后才可以去调用 3.测试接口的性能:例如:我们需要考虑某一个接口在N多个用户访问的时候工作的压力 4.测试接口的数据:保证接口返回的数...

获取到集成指定类,接口等的类

利用反射获取到实现当前接口的类, 本文只做代码验证,无任何实际意义 具体代码如下 1 namespace General.Cons 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 //假设从接...

Linux设备驱动程序学习(17)-USB 驱动程序(二)

内核使用2.6.29.4USB设备其实很复杂,但是Linux内核提供了一个称为USB core的子系统来处理了大部分的复杂工作,所以这里所描述的是驱动程序和USB core之间的接口。 在USB设备组织结构中,从上到下分为设备(device)、配置(config)、接口(interface)和端点(endpoint)四个层次。 对于这四个层次的简单描述如下...

Jmeter接口压力测试(先登录再测接口)

Jmeter测试接口(包括登陆操作) 1.      创建HTTP Request先登录 参考: http://blog.csdn.net/ab_2016/article/details/78249686 注意:勾选FollowRedirects 自动重定向Redirect Automatically:HttpClient接收到请求后,如果请求中包含重定...

高端存储发展趋势

1. 高端存储的技术发展趋势 松耦合 高端存储刚出现的时候,采用的是紧耦合的多控体系架构。紧耦合架构的特点就是所有的资源都是物理集中在一起的,这些资源通常包括前端接口,后端接口和Cache,一般都插在一个大机箱里。随着技术的发展,特别用户对总体拥有成本(TCO)和可扩展性的追求,现在的高端存储厂商大部分采用了松耦合的多控体系架构。它们都有一个特点,每...

2、k8s api访问-token、RBAC、证书

1、token方式使用k8s restful api思维导图 https://liumiaocn.blog.csdn.net/article/details/100518110 token方式使用k8s restful api思维导图 2、apiserver认证 2.1、Kubernetes apiserver认证 Kubernetes apiserve...