【问题标题】:How can I replicate this cookie functionality on my Web Client?如何在我的 Web 客户端上复制此 cookie 功能?
【发布时间】:2012-05-11 02:52:14
【问题描述】:

根据我的阅读,跨域发送 cookie 是不可能的(据我了解,浏览器出于隐私原因阻止了它们)。不过,我希望有人能告诉我解决方法。

我已经在我们的 .Net winForms 客户端中实现了这一点,但是我无法让它在我们的网络软件上运行。

场景:我有我的网站,这需要调用第 3 方系统,该系统使用带有 XML 的 rest 实现,存在于客户防火墙内并且无法从其办公室外部访问(VPN 也不是一个选项) .

我设置了我的 cookie:

$.cookie('name', 'value', {path : '/', domain : '192.168.254.164'});

并提出发帖请求

$.post(call, function(d) {}, 'text')
.success(function(d) {... /*do something*/

但是,cookie 没有发送(请参阅下面的请求和响应标头)

Request Headers
Accept    text/plain, */*; q=0.01
Accept-Encoding   gzip, deflate
Accept-Language   en-gb,en;q=0.5
Connection    keep-alive
Host  192.168.254.164:8080
Origin    http://localhost:27249
Referer   http://localhost:27249/index.html
User-Agent    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:11.0) Gecko/20100101 Firefox/11.0


Response Headers
Access-Control-Allow-Orig...  http://localhost:27249
Cache-Control no-cache
Content-Type  application/xml;charset=UTF-8
Date  Tue, 01 May 2012 15:14:58 GMT
Server    Sun Java System Application Server 9.1_01
Set-Cookie    JSESSIONID=8f7fbcd40348c0b5d912830bca8a; Path=/App
Transfer-Encoding chunked
X-Powered-By  Servlet/2.5

我收到的回复告诉我我未经授权(这是因为未设置 cookie)。

我不能修改第三方服务器上的任何东西,所以在代理服务器上,我不能使用 JSONP,因为一切都在 XML 中。

为了调试,我尝试在发送之前读取 cookie,但结果为“null”:

alert($.cookie(_svcMnuCookieSessionIdKey));

我是网络开发新手,所以这可能是一个奇怪的问题 - 但正如您从响应标题中看到的那样,我相信我收到了一个 cookie(我在登录时收到了相同的 cookie) - 作为浏览器处理cookies,它不应该保存它并自动将其应用于我的请求吗?而不是我必须像上面那样手动添加它?尽管如此,JSESSIONID 看起来在两个请求中都有不同的值,并且规范说我必须使用我登录时获得的原始 JSESSIONID 作为我的 cookie 的值。

在我的 .Net 应用程序中,我这样做类似于:

 Dim httpWebRequest As Net.HttpWebRequest = CType(Net.WebRequest.Create("http://192.168.254.164:8080/App/RestfulService"), Net.HttpWebRequest)

 httpWebRequest.UserAgent = My.Application.Info.AssemblyName
 httpWebRequest.KeepAlive = True 'set the connection keep-alive (this is the default)
 httpWebRequest.Headers.Set(Net.HttpRequestHeader.Pragma, "no-cache") 'we don't want caching to take place so we need to set the pragma header to say we don't want caching
 httpWebRequest.Method = "POST"

 If Not String.IsNullOrEmpty(_sessionId) Then 'it isn't used on some request, so don't add it if it is nothing
     Dim cookie As New System.Net.Cookie("JSESSIONID", _sessionId)
     cookie.Domain = New Uri("http://192.168.254.164:8080/App/RestfulService").Host
     httpWebRequest.CookieContainer = New Net.CookieContainer
     httpWebRequest.CookieContainer.Add(cookie)
 End If

 httpWebRequest.ContentType = "application/x-www-form-urlencoded"

 Dim postData As Byte() = New System.Text.UTF8Encoding(False).GetBytes(RichTextBox1.Text)

 httpWebRequest.ContentLength = postData.Length

 Using tmpStream As IO.Stream = httpWebRequest.GetRequestStream
     tmpStream.Write(postData, 0, postData.Length)
 End Using

 Dim httpWebResponse As Net.HttpWebResponse = CType(httpWebRequest.GetResponse, Net.HttpWebResponse)

 If WebValidation.WebResponseHasContent(httpWebResponse) Then

     Dim str As String = String.Empty
     'Read the raw HTML from the request
     Using sr As New IO.StreamReader(httpWebResponse.GetResponseStream, System.Text.Encoding.UTF8)
         str = sr.ReadToEnd
     End Using

 End If

Return str

那么,这是一个跨域 cookie 请求吗?以及如何在我的 Web 客户端中重新创建此功能?

【问题讨论】:

  • 如果任何类型的跨域 cookie 都是可能的,那不是一个巨大的安全漏洞吗?
  • 您的网络服务器是否与它尝试调用的第 3 方系统位于同一内部网络?
  • @edr - 不,我们的网络服务器在互联网上,第 3 方服务器位于客户防火墙后面,无法访问。在我的开发场景中,他们都在同一个办公室。
  • 当你将它部署到生产环境中并且你的网络服务器在外部世界并且第 3 方应用程序在防火墙内时,它是如何工作的?如果您尝试通过客户端访问第 3 方,那么这些请求将来自不同的 IP,并且很难在防火墙中打开规则以允许访问(而不是将其设为公共访问)。希望你有一个计划。
  • 答案在这里:stackoverflow.com/a/10353875。中间的 web 客户端站点并使用 jQuery 将 httprequests 发布到其他服务器,

标签: jquery post cookies cross-domain


【解决方案1】:

我认为您不是在尝试设置跨域 cookie。系统不会要求您这样做。通常在这种情况下,您需要与第 3 方系统进行一些握手以获取令牌,或者在您的情况下首先获取 JSESSIONID(来自系统)。但是,从外观上看,您试图在 3rd 方系统上设置 cookie,而不是从系统接受 cookie。那有意义吗?所以我期望的是,您需要向第 3 方系统发出请求以获取令牌,然后在您尝试获取 xml 时为每个后续请求传递该令牌。

我认为在您的场景中,您拥有自己的网络应用程序和 3rd 方应用程序。您可能会感到困惑的是在您的浏览器上设置的 cookie 与在您的网络应用程序上“设置”的 cookie(用于身份验证)。

当您通过第 3 方系统进行身份验证并返回 JSESSIONID 后,请尝试将后续请求标头设置为包含 'cookie' 标头,其中包含 JSESSIONID 或第 3 方系统进行身份验证所需的任何内容。

请记住,在这种情况下,当您从您的网络应用程序调用第 3 方作为服务时,您的网络应用程序就是调用第 3 方的“浏览器”。因此,当它对第 3 方系统进行后续调用时,它必须通过假装存在 cookie(包含您的身份验证 sessionid)来模仿浏览器 - 您可以通过设置“cookie”请求标头来做到这一点。

【讨论】:

  • 你说的很有道理。如何设置我的后续请求标头以包含包含 JSESSIONID 的“cookie”标头? (我假设浏览器会自动处理这个问题,如果没有,那就是我沿着设置它的路线走的时候)
  • 交互是在你的web-app和第3方系统之间,你的浏览器只和你的web-app交互。所以就第 3 方而言,网络应用程序就是浏览器。因此,如果第 3 方应用程序需要具有正确 sessionid 的 cookie,您必须通过创建请求标头自己制作。你的网络应用是用什么编码的?
  • ...jQuery、jQuery Mobile 和 HTML。我没有任何影响这一点的服务器端代码。
  • 很确定您可以使用 jQuery 设置请求标头(以及因此设置的 cookie) - 您查看过文档吗?
  • 我认为你可以使用它 - api.jquery.com/jQuery.ajax 但是我不确定如何使用它来设置我在之前的请求中收到的 cookie。
【解决方案2】:

你不能。浏览器制造商花费了大量时间和精力来确保您尝试完成的事情不会发生,即使您确实找到了临时解决方案,它也会被视为安全漏洞并可能在下一个版本中修补。

相反,尝试弄清楚如何将所需的信息传递到 Web 服务中。

【讨论】:

  • 第 3 方已指定必须向他们发送 cookie。请您确认我正在尝试设置跨域 cookie 吗? - 服务器确实在响应中向我发送了一个。
  • 听起来您需要对 Web 服务进行身份验证才能使用它。您需要弄清楚他们需要什么才能进行身份验证。
  • 我已经通过了身份验证,我调用了他们的登录方法,它返回一个具有各种属性的对象,其中一个是成功,另一个是会话 ID。在响应标头中,我还得到 Set-Cookie JSESSIONID=8f7ea58cfc0bb0fba86ec2b1f668;路径=/子文件夹名称。在我的 Windows 客户端中,如果我没有为后续调用附加 cookie,我会得到 unauth 响应。这显然是 cookie 的问题,而不是 Web 服务的身份验证问题。
猜你喜欢
  • 2021-02-10
  • 2013-11-10
  • 2017-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多