为了账号安全,请及时绑定邮箱和手机立即绑定

网站流量的Cookie管理 网络客户端

网站流量的Cookie管理 网络客户端

跃然一笑 2022-09-22 19:41:16

我有一个 Web 客户端,它将一个带有登录凭据的 JSON 对象发送到远程服务器。然后,远程服务器返回该 Cookie。之后,我需要将数据与cookie一起发布到该远程服务器。但是,我无法弄清楚如何在POST中重复使用cookie。


据我所知,登录响应给出了以下结构,但是在POST上设置cookie的代码需要或只是。MultiValueMap<String, ResponseCookie>MultiValueMap<String, String>cookie(String, String)


我假设我一定错过了一些转换器的魔力,但那又如何呢?我甚至需要退回整个饼干吗?


饼干看起来像这样;


{SSO_Sticky_Session-47873-loadBalancedAdminGrp=[SSO_Sticky_Session-47873-loadBalancedAdminGrp=BNAMAKAKJABP; Path=/; HttpOnly], AUTH_TOKEN=[AUTH_TOKEN=v0l3baVZejIKjdzA1KGpkz4ccnosE6rKLQig1D2bdb-voFmVrF_aaYgzWl3Yc8QK; Path=/], uid=[uid=sjzipQdBtU30OlVbPWtDK2625i24i6t6g3Rjl5y5XcI=; Path=/], __cfduid=[__cfduid=dd872f39fd1d3bfe2a5c7316cd9ff63cd1554623603; Path=/; Domain=.aDomain.net; Max-Age=31535999; Expires=Mon, 6 Apr 2020 07:53:23 GMT; HttpOnly], JSESSIONID=[JSESSIONID=A264A713AD060EE12DA8215AEF66A3C0; Path=/aPath/; HttpOnly]}

我的代码在下面。为了简洁起见,我删除了内容类型;


WebClient webClient = WebClient.create("https://remoteServer");

MultiValueMap<String, ResponseCookie> myCookies;


webClient

  .post()

  .uri("uri/login")

  .body(Mono.just(myLoginObject), MyLogin.class)

  .exchange()

  .subscribe(r -> 

    System.err.println("Received:" + r.cookies());

    myCookies = r.cookies();

   );


webClient

  .post()

  .uri("/uri/data")

  .cookies(????) // what goes here ??

  .body(....)

  .exchange();


查看完整描述

3 回答

?
当年话下

TA贡献1554条经验 获得超9个赞

在编写服务器端Java和JSP多年之后,我在很大程度上忽略了cookie的概念,因为管理是由(例如)服务器端的Tomcat和客户端的浏览器负责的。在Spring中,任何对cookie处理的搜索总是集中在Spring服务器上,很少关注Spring实际上是另一个服务器的客户端。WebClient 的任何示例都是过于简单化的,并且没有采用任何形式的安全协商。

在阅读了饼干解释维基百科饼干和饼干标准RFC6265之后,对我来说,为什么传入的饼干在课堂上,而传出的饼干是.传入的 Cookie 在 (例如) 和 上具有其他元数据。ResponseCookieStringDomainPathMax-Age

对于我的实现,供应商没有指定需要返回哪些 cookie,因此我最终返回了所有这些 Cookie。因此,我修改后的代码如下;

WebClient webClient = WebClient.create("https://remoteServer");

MultiValueMap<String, String> myCookies = new LinkedMultiValueMap<String, String>()


webClient

  .post()

  .uri("uri/login")

  .body(Mono.just(myLoginObject), MyLogin.class)

  .exchange()

  .subscribe(r -> 

      for (String key: r.cookies().keySet()) {

        myCookies.put(key, Arrays.asList(r.cookies().get(key).get(0).getValue()));

      }

   );


webClient

  .post()

  .uri("/uri/data")

  .cookies(cookies -> cookies.addAll(myCookies))

  .body(....)

  .exchange();


查看完整回答
反对 回复 2022-09-22
?
动漫人物

TA贡献1480条经验 获得超10个赞

由于已被弃用,但此线程出现在流行的搜索计算机上,因此让我使用下面的代码示例添加一个代码示例以供将来参考。.exchange().exchangeToMono()


请注意,我使用一个,它将在bean发送的每个请求之前发送授权请求:ExchangeFilterFunctionwebClient


@Bean("webClient")

public WebClient webClient(ReactorResourceFactory resourceFactory,

    ExchangeFilterFunction authFilter) {

    var httpClient = HttpClient.create(resourceFactory.getConnectionProvider());

    var clientHttpConnector = new ReactorClientHttpConnector(httpClient);

    return WebClient.builder().filter(authFilter).clientConnector(clientHttpConnector)

        .build();

}


@Bean("authWebClient")

public WebClient authWebClient(ReactorResourceFactory resourceFactory) {

    var httpClient = HttpClient.create(resourceFactory.getConnectionProvider());

    var clientHttpConnector = new ReactorClientHttpConnector(httpClient);

    return WebClient.builder().clientConnector(clientHttpConnector).build();

}


@Bean

public ExchangeFilterFunction authFilter(@Qualifier("authWebClient") WebClient authWebClient,

    @Value("${application.url:''}") String url,

    @Value("${application.basic-auth-credentials:''}") String basicAuthCredentials) {

return (request, next) -> authWebClient.get()

    .uri(url)

    .header("Authorization", String.format("Basic %s", basicAuthCredentials))

    .exchangeToMono(response -> next.exchange(ClientRequest.from(request)

        .headers(headers -> {

            headers.add("Authorization", String.format("Basic %s", basicAuthCredentials));

        })

        .cookies(readCookies(response))

        .build()));

}


private Consumer<MultiValueMap<String, String>> readCookies(ClientResponse response) {

return cookies -> response.cookies().forEach((responseCookieName, responseCookies) ->

    cookies.addAll(responseCookieName,

        responseCookies.stream().map(responseCookie -> responseCookie.getValue())

            .collect(Collectors.toList())));

}


查看完整回答
反对 回复 2022-09-22
?
幕布斯7119047

TA贡献1466条经验 获得超8个赞

这个答案的灵感来自@J。


.exchange不应再使用。取而代之的是一个名为 的新方法。在 Lambda 的帮助下,可以编辑和转换响应。饼干也可以被提取。在此示例中,Cookie 显示在控制台中。但它们也可以毫无问题地保存。.exchangeToMono


    public String getWebsiteWithCookies() {

        var webClient = WebClient.create();


        return webClient.post()

                .uri("url")

                // Your headers & so here

                .exchangeToMono(response -> {

                    MultiValueMap<String, ResponseCookie> cookies = response.cookies();

                    for (var cookie : cookies.entrySet()) {

                        System.out.println(cookie.getKey() + " : " + cookie.getValue());

                    }


                    return response.bodyToMono(String.class);

                })

                .block();

    }


查看完整回答
反对 回复 2022-09-22

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信