基于PACT JVM服务端请求添加OAuth2 Token的实现疑问
在Pact JVM中为请求添加OAuth2 Token的解决方案
嘿,我来帮你搞定Pact JVM里添加OAuth2 Token到请求头的问题!你已经成功在@BeforeClass里拿到了Token,现在只需要把它注入到Pact发送的请求里就行,@State方法其实是用来设置提供者的状态(比如让提供者模拟用户已登录的场景),不是用来修改消费者请求的,我给你两种靠谱的实现方式:
方法一:自定义HttpTarget添加请求拦截器
这种方法最直接,我们可以在初始化HttpTarget的时候,添加一个请求拦截器,让它在每个请求发送前自动把Token加到Authorization头里。
注意:为了确保Token已经获取到再初始化Target,我们可以把Target改成静态变量,在@BeforeClass里完成初始化:
public class TransactionPact { private static Target target; private static FinanceApiToken financeApiToken; @BeforeClass public static void getAuthorisationToken() { // 先获取OAuth2 Token HttpHeaders header = new HttpHeaders(); header.set("Content-Type", "application/x-www-form-urlencoded"); header.set("Authorization", "Basic ZmluLWFwaTphcGktc2VjcmV0"); header.set("Connection", "keep-alive"); header.set("cache-control", "no-cache"); HttpEntity<String> request = new HttpEntity<>("username=sap&password=password2&grant_type=password", header); RestTemplate restTemplate = new RestTemplate(); ResponseEntity<FinanceApiToken> response = restTemplate.postForEntity("http://127.0.0.1:8080/oauth/token", request, FinanceApiToken.class); if (response.getStatusCode() != HttpStatus.OK) { throw new HTTPException(response.getStatusCodeValue()); } financeApiToken = response.getBody(); // 初始化Target,添加请求拦截器注入Token target = new HttpTarget.Builder("http://localhost", 8332) .requestInterceptor((request, body, execution) -> { // 把Token以Bearer格式加到请求头 request.getHeaders().set("Authorization", "Bearer " + financeApiToken.getAccessToken()); return execution.execute(request, body); }) .build(); } // 提供Target给Pact测试 @TestTarget public final Target getTarget() { return target; } @State("the consumer is authorised") public void authorise() { // 这里只需要处理提供者的状态,比如告诉提供者当前用户已授权 // 比如如果是本地测试的提供者,可以在这里调用接口设置用户状态 } // 你的Pact测试方法示例 @Pact(provider = "FinanceApi", consumer = "TransactionService") public RequestResponsePact createTransactionPact(PactDslWithProvider builder) { return builder .given("the consumer is authorised") .uponReceiving("a request to fetch user transactions") .path("/api/transactions") .method("GET") // 不需要手动加Authorization头,拦截器会自动处理 .willRespondWith() .status(200) .body(PactDslJsonArray.arrayEachLike() .stringType("transactionId", "TXN-001") .numberType("amount", 500.00) .stringType("currency", "USD") ) .toPact(); } }
方法二:全局请求过滤器(适用于所有Pact测试)
如果你的多个测试类都需要添加OAuth2 Token,可以用Pact的全局请求过滤器,一次性配置所有请求:
@BeforeClass public static void setupPactRequestFilter() { // 先获取Token(和你原来的代码一样) // ... // 设置全局请求过滤器 PactVerification.setRequestFilter(request -> { request.addHeader("Authorization", "Bearer " + financeApiToken.getAccessToken()); }); }
这种方式会对当前类下的所有Pact请求生效,适合统一配置的场景。
关键说明
@State方法的核心作用是同步消费者和提供者的状态:比如你告诉提供者“现在消费者是已授权状态”,提供者需要模拟这个状态(比如在数据库中创建一个已登录的用户),而不是修改消费者的请求。- 拦截器/过滤器的方式能确保Token在请求发送前被注入,避免手动在每个Pact里重复添加头信息,也支持动态获取的Token。
内容的提问来源于stack exchange,提问作者sdicola
相关产品推荐
相关产品推荐

