SpringCloud系列教程(十一):token验证
之前我们完成了gateway传递token到微服务中,但是这还不够,因为有时候我们微服务是一个调用链路,每个微服务的请求可以来自于网关也可以来自于其他微服务,我们只完成了gateway传递token,还没有完成微服务之间使用openfeign发送请求时的token传递。
1、我们在common项目里加一个类,把之前我们创建的那个openfeign-demo项目(时间过去有点久了,翻看一下前文)中的DefaultFeignConfig文件复制到common的config包下。openfeign框架给我们预留了一个拦截器RequestInterceptor,所以我们把openfeign的依赖复制到common的pom文件里并添加拦截器。
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
package com.mj.common.config;
import cn.hutool.core.util.StrUtil;
import com.mj.common.tool.UserTool;
import feign.Logger;
import feign.Request;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;
import java.util.concurrent.TimeUnit;
public class DefaultFeignConfig {
@Bean
public Logger.Level feignLogLevel() {
return Logger.Level.FULL;
}
@Bean
public Request.Options options() {
//第一个参数是连接超时时间,第二个参数是处理超时时间
return new Request.Options(2000, TimeUnit.MILLISECONDS, 2000, TimeUnit.MILLISECONDS, true);
}
@Bean
public RequestInterceptor userRequestInterceptor() {
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
String userid = UserTool.getUserId();
if (StrUtil.isNotBlank(userid)) {
requestTemplate.header("userid", userid);
}
}
};
}
}
2、这样就可以清理掉openfeign中的重复文件了,由于我们在学习过程中修改了不少东西,所以之前的openfeign-demo也要再修改一下。修改主启动类,把common里的config类扫描进去。
package com.mj.openfeign;
import com.mj.common.config.DefaultFeignConfig;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)
@SpringBootApplication(scanBasePackages = "com.mj")
public class OpenFeignDemoApplication {
public static void main(String[] args) {
SpringApplication.run(OpenFeignDemoApplication.class, args);
}
}
3、修改NacosClientDemoClient文件,添加调用talk接口,并且要把更新的接口地址修改好。
package com.mj.openfeign.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("nacos-client-demo")
public interface NacosClientDemoClient {
@GetMapping("/nacos-client-demo/api/call")
String testCall();
@GetMapping("/nacos-client-demo/api/talk")
String testTalk();
}
4、修改NacosClientController,添加一个调用talk的测试接口。
package com.mj.openfeign.client;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient("nacos-client-demo")
public interface NacosClientDemoClient {
@GetMapping("/nacos-client-demo/api/call")
String testCall();
@GetMapping("/nacos-client-demo/api/talk")
String testTalk();
}
5、网关里要添加对openfeign-demo的路由配置。
spring:
main:
# gateway组件中的spring-boot-starter-webflux和springboot作为web项目启动必不可少的spring-boot-starter-web出现冲突
web-application-type: reactive
application:
name: gateway-demo
cloud:
nacos:
server-addr: 192.168.3.54:80
username: nacos
password: nacos
discovery:
group: devops
namespace: sit
config:
namespace: sit
group: devops
gateway:
routes:
- id: nacos-client-demo #指定服务名
uri: lb://nacos-client-demo #去注册中心找这个服务名
predicates: #断言,匹配访问的路径
- Path=/nacos-client-demo/api/** #服务访问路径
filters: # 过滤器
- AddRequestHeader=headername, I am a header! # 添加请求头
- My=zhangsan,lisi,wangwu
- id: open-feign-demo
uri: lb://open-feign-demo
predicates:
- Path=/open-feign-demo/api/**
config:
import: nacos:${spring.application.name}?refresh=true
server:
port: 8888
6、重启服务,通过curl命令带有token进行调用openfeign-demo,再由openfeign-demo调用nacos-client-demo中的talk接口。
curl -H "token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyTmFtZSI6InpoYW5nc2FuIiwidXNlcklkIjoiMTIzIiwiZXhwIjoxN zQwNzU1NDE2fQ.Xqpgk_lqhpxIIvxSo70mb3LQuozREIOituLyZKKYYaA" http://127.0.0.1:8888/open-feign-demo/api/talk
hi,123
可见返回结果页正确解析到了userId,这样我们就基本完成了token在微服务体系中的传递功能,当然在日常工作中还会有其他的做法,万变不离其宗,大家就按照咱们练习的样子去改造就可以了。