假设
我假设您正在寻找一种使用基于 cookie 的身份验证来针对 REST 服务器进行身份验证的方法,基本上而不是访问网页。
此外,我假设您希望避免将您的 cookie 暴露给不应将 cookie 发送到的网站。
使用 cookie 进行服务器到服务器的通信是很不寻常的,但并非不可能(我之前已经破解过类似的东西)。不过,您想要做的听起来正是这样:从一台服务器设置/获取 cookie,然后在另一台服务器(您想要调用的 RESTful JSON 服务器)上存储和使用这些 cookie。我不太清楚您是否拥有设置 cookie 的服务器,以及这些 cookie 会在哪里使用,但我会尽力根据您目前告诉我们的内容给出一个好的答案。
基于 Cookie 的身份验证流程
既然你正在谈论 cookie 属性,例如Secure
, HttpOnly
, SameSite
等等,你似乎想使用Set-Cookie
标题某处。当客户端向服务器发出初始 HTTPS 请求时(这里稍微简化一下),此标头通常从服务器发送到客户端(通常是浏览器,但在您的情况下是 Spring 应用程序)。
The Cookie
标头仅携带键值对(例如Cookie: JSESSIONID=...; YOURCOOKIE=...
),客户端使用它来将 cookie 的存储值发送回服务器以供后续请求使用。哪些 cookie 是由浏览器根据 cookie 中的设置确定的SET-COOKIE
他们从服务器收到的标头。
流程示例:
- 客户端向服务器发送 HTTPS 请求,例如
GET https://subdomain.yourdomain.com/do/
- 在我们的示例中,服务器发送一个响应,其中包含正文中的页面 HTML(或者在您的情况下为 JSON)和一堆标头
Set-Cookie: JSESSIONID=<cookie-value>; Domain=yourdomain.com; SameSite: Lax; Secure; HttpOnly
(或者像 Content-Security-Policy 这样的标头可以比 SameSite 进行更细粒度的控制)。
- 客户端(通常是浏览器,但也可能是您的 Spring 应用程序)接收
Set-Cookie
header 并存储它们(临时/在请求上下文中)以及所有 cookie 属性。
- 当向服务器发出另一个请求时,客户端仅将 cookie 作为键值对发送到
Cookies
标头。浏览器具有确定 cookie 是否随请求一起发送的规则(请参阅https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent)。如果您只想在 Spring 应用程序中发送正确的 cookie,这些附加属性可能不会产生任何效果,并且您需要自己模拟所有浏览器规则,或者只为您想要实际发送的 cookie 编写自定义逻辑。
你可以如何尝试让它发挥作用
Cookie 通常在浏览器中生成。浏览器(客户端)向 HTTP(S) 服务器发出请求并获取响应,并在响应标头中返回 Set-Cookie 属性。您可以对您的应用程序执行相同的操作,只需过滤掉您需要的 cookie。
浏览器通常会存储这些 cookie,您可以在该页面的浏览器的 DevTools 中看到它们。 (例如,请参阅此页面,了解如何在 Chrome 中执行此操作:https://developer.chrome.com/docs/devtools/application/cookies/ https://developer.chrome.com/docs/devtools/application/cookies/)。您的 Spring 应用程序需要将这些 cookie 存储在 Spring 上下文中的某个位置。有关更多详细信息,如果您想重用服务器请求中的 cookie,也许这会有所帮助:带 cookie 的 RestTemplate 客户端 https://stackoverflow.com/questions/22853321/resttemplate-client-with-cookies)
要指定一个 cookie 来指定它对哪些域、路径等有效,您可以使用以下内容的组合作为Set-Cookie
HttpHeader 中的字段,例如Domain
, Path
, SameSite
(有关每个属性的详细信息,请参见https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Set-Cookie)。您可以在此处了解浏览器验证规则的工作原理:https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#define_where_cookies_are_sent
RestTemplate示例代码
为了在您的restTemplate请求中使用这些cookie,您可以使用以下代码(基于您的代码示例):
HttpHeaders requestHeaders = new HttpHeaders();
ResponseCookie cookie = new ResponseCookie("JSESSIONID", session.getValue() + "; HttpOnly; Secure; SameSite=Strict/Lax; Domain: yourdomain.com");
requestHeaders.add(cookie);
HttpEntity requestEntity = new HttpEntity(null, requestHeaders);
ResponseEntity rssResponse = restTemplate.exchange(
"https://jira.example.com/sr/jira.issueviews:searchrequest-xml/18107/SearchRequest-18107.xml?tempMax=1000",
HttpMethod.GET,
requestEntity,
Rss.class);
Rss rss = rssResponse.getBody();
根据您使用的 Spring 版本,此代码可能适合您,也可能不适合您。如果有更多详细信息,我可能会更新我的回复
进一步阅读:
-
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpEntity.html https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpEntity.html
-
如何建造Set-Cookie
标头:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/ResponseCookie.ResponseCookieBuilder.html https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/ResponseCookie.ResponseCookieBuilder.html
-
如何建造Cookie
标头:https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpCookie.html https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/http/HttpCookie.html
结束语
这是我在 StackOverflow 上的第一个回答,我知道它有点长。让我知道什么是有帮助的,也许有更多的背景信息,我也许可以根据您的需求稍微调整/简化它。当我不得不做和你类似的事情时,我最近学到了很多关于cookie的知识,所以我希望它能有所帮助。