【问题标题】:Spring Boot RestTemplate get Cookie from CallbackSpring Boot RestTemplate 从回调中获取 Cookie
【发布时间】:2022-07-14 19:41:16
【问题描述】:

我想使用 Spring RestTemplate 从作为登录 URL 的重定向 URL 的回调中检索 jwt 令牌。

我已经能够连接到登录 URL,我已经能够跟随重定向链接到回调,但我无法检索存储在回调的响应标头中的令牌。

RestTemplate restTemplate = new RestTemplate();
String url = my_login_url;

HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
map.add(my_login);
map.add(my_password);

HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

final HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
final HttpClient httpClient = HttpClientBuilder.create()
                .setRedirectStrategy(new LaxRedirectStrategy())
                .build();
factory.setHttpClient(httpClient);
restTemplate.setRequestFactory(factory);

ResponseEntity<String> response = restTemplate.exchange(url,
                HttpMethod.POST,
                request,
                String.class);

// OUCH !! response does not contain the token I'm trying to retrieve !! The token is in the header of the callback !!

谁能帮我理解如何访问回调的标头?

【问题讨论】:

    标签: java spring-boot callback token response-headers


    【解决方案1】:

    经过一些研究,我能够找到一种方法来检索该令牌,这对我来说更像是一种黑客攻击,而不是实际的解决方案。
    这个想法是 apache HttpClient 包含一个只有我需要的令牌的 cookie 存储。不幸的是,HttpClient 没有任何 getter,只有 execute 方法,而且我已经在 RestTemplates 上。
    但是,可以在构建 HttpClient 实例时将 Cookie Store 作为参数传递。该 Cookie 存储将在发布身份验证请求时被填充。

    最终版本的代码如下所示:

    public void getCookies() {
    
     RestTemplate restTemplate = new RestTemplate();
     String url = my_login_url;
    
     HttpHeaders headers = new HttpHeaders();
     headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
    
     MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
     map.add("username_key", my_user);
     map.add("password_key", my_password);
    
     HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);
    
     final HttpComponentsClientHttpRequestFactory factory = new 
     HttpComponentsClientHttpRequestFactory();
     CookieStore basicCookieStore = new BasicCookieStore();
     final HttpClient httpClient = HttpClientBuilder.create()
                    .setRedirectStrategy(new LaxRedirectStrategy())
                    .setDefaultCookieStore(basicCookieStore)
                    .build();
     factory.setHttpClient(httpClient);
     restTemplate.setRequestFactory(factory);
    
     restTemplate.exchange(url,
                    HttpMethod.POST,
                    request,
                    String.class);
    
     Cookie cookie  = basicCookieStore.getCookies().stream()
                    .findFirst()
                    .orElseThrow(() -> new RuntimeException(url));
     System.out.println(cookie.getValue());
    }
    

    请注意,我什至对 restTemplate.exchange 查询的响应都不感兴趣。

    【讨论】:

      【解决方案2】:

      你可以使用

      response.getHeaders().get(HttpHeaders.SET_COOKIE);
      

      (当客户端通过“Cookie”标头发送其拥有的cookie时,服务器发送cookie以设置“Set-Cookie”标头。)

      这会返回一个列表,因为每个 cookie 都将位于同名的额外标头中。

      【讨论】:

      • 您的回答中有几个问题:首先,当我说我需要访问重定向响应的标头时,这给出了响应的标头(先验);第二,不是ResponseEntity.SET_COOKIE,而是HttpHeaders.SET_COOKIE
      • 对此我深表歉意,但即使再阅读您的问题两次,也只有在您的评论的帮助下,我才能够理解您的真正需求。但是所以我的错误答案至少帮助我正确理解了问题;)对于错误的常数:完全归咎于我,我当然会解决这个问题!
      • 很抱歉。我承认我的用例实际上有点棘手。使用 Springboot 更加棘手,因为部分代码隐藏在 Configuration 类中,并且一切都是单例的。无论如何,只是为了让你知道,我仍然给你一个“-1”的答案,因为它真的没有回答我的问题。但我完全感谢你的尝试和如此全面,因为我必须承认我的评论写得有点仓促,有点苛刻......
      猜你喜欢
      • 1970-01-01
      • 2018-07-04
      • 1970-01-01
      • 2020-03-13
      • 1970-01-01
      • 2023-04-03
      • 2019-06-06
      • 1970-01-01
      • 2019-04-28
      相关资源
      最近更新 更多