跨域 Cookie

发布于 2024-09-11 22:59:48 字数 287 浏览 7 评论 0原文

我在两个不同的域中有两个网络应用程序 WebApp1 和 WebApp2。

  1. 我在 HttpResponse 的 WebApp1 中设置 cookie。
  2. 如何从WebApp2中的HttpRequest读取相同的cookie?

我知道这听起来很奇怪,因为 cookie 是特定于给定域的,我们无法从不同的域访问它们;不过,我听说过跨域 cookie,它可以在多个网络应用程序之间共享。如何使用跨域cookie来实现这个要求?

注意:我正在尝试使用 J2EE webapps

I have two webapps WebApp1 and WebApp2 in two different domains.

  1. I am setting a cookie in WebApp1 in the HttpResponse.
  2. How to read the same cookie from HttpRequest in WebApp2?

I know it sounds weird because cookies are specific to a given domain, and we can't access them from different domains; I've however heard of CROSS-DOMAIN cookies which can be shared across multiple webapps. How to implement this requirement using CROSS-DOMAIN cookies?

Note: I am trying this with J2EE webapps

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(17

风吹过旳痕迹 2024-09-18 22:59:48

是的,完全可以通过domain2.exampledomain1.example获取cookie。我的社交网络的社交插件也遇到了同样的问题,经过一天的研究,我找到了解决方案。

首先,在服务器端,您需要具有以下标头:

header("Access-Control-Allow-Origin: http://origin.domain:port");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST");
header("Access-Control-Allow-Headers: Content-Type, *");

在 PHP 文件中,您可以使用 $_COOKIE[name]

其次,在客户端:

在 AJAX 请求中,您需要包含 2参数

crossDomain: true
xhrFields: { withCredentials: true }

示例:

type: "get",
url: link,
crossDomain: true,
dataType: 'json',
xhrFields: {
  withCredentials: true
}

Yes, it is absolutely possible to get the cookie from domain1.example by domain2.example. I had the same problem for a social plugin of my social network, and after a day of research I found the solution.

First, on the server side you need to have the following headers:

header("Access-Control-Allow-Origin: http://origin.domain:port");
header("Access-Control-Allow-Credentials: true");
header("Access-Control-Allow-Methods: GET, POST");
header("Access-Control-Allow-Headers: Content-Type, *");

Within the PHP-file you can use $_COOKIE[name]

Second, on the client side:

Within your AJAX request you need to include 2 parameters

crossDomain: true
xhrFields: { withCredentials: true }

Example:

type: "get",
url: link,
crossDomain: true,
dataType: 'json',
xhrFields: {
  withCredentials: true
}
↙温凉少女 2024-09-18 22:59:48

正如其他人所说,您不能共享 cookie,但您可以执行以下操作:

  1. 将所有 cookie 集中在一个域中,例如
  2. 当用户向 example 发出请求时使用 cookiemaker.example。 com 你将他重定向到 cookiemaker.example
  3. cookiemaker.example 将他重定向回 example.com 并提供您需要的信息

当然,它并不完全安全,您必须在应用程序之间创建某种内部协议才能做到这一点。

最后,如果您在每个请求中都执行类似的操作,但如果只是第一个请求则不会,这对用户来说会非常烦人。

但我认为没有其他办法。

As other people say, you cannot share cookies, but you could do something like this:

  1. centralize all cookies in a single domain, let's say cookiemaker.example
  2. when the user makes a request to example.com you redirect him to cookiemaker.example
  3. cookiemaker.example redirects him back to example.com with the information you need

Of course, it's not completely secure, and you have to create some kind of internal protocol between your apps to do that.

Lastly, it would be very annoying for the user if you do something like that in every request, but not if it's just the first.

But I think there is no other way.

树深时见影 2024-09-18 22:59:48

据我所知,cookies受到“同源”政策的限制。但是,通过 CORS,您可以接收并使用“服务器 B”cookie 在“服务器 B”上建立来自“服务器 A”的持久会话。

不过,这需要“服务器 B”上的一些标头:

Access-Control-Allow-Origin: http://server-a.example.com
Access-Control-Allow-Credentials: true

并且您需要在所有“服务器 A”请求上发送标志“withCredentials”(例如:xhr.withCredentials = true;

您可以在这里阅读:

http://www.html5rocks.com/ en/tutorials/cors/

https://developer.mozilla.org /en-US/docs/HTTP/Access_control_CORS

As far as I know, cookies are limited by the "same origin" policy. However, with CORS you can receive and use the "Server B" cookies to establish a persistent session from "Server A" on "Server B".

Although, this requires some headers on "Server B":

Access-Control-Allow-Origin: http://server-a.example.com
Access-Control-Allow-Credentials: true

And you will need to send the flag "withCredentials" on all the "Server A" requests (ex: xhr.withCredentials = true;)

You can read about it here:

http://www.html5rocks.com/en/tutorials/cors/

https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS

§普罗旺斯的薰衣草 2024-09-18 22:59:48

不存在跨域 cookie 这样的东西。您可以在 foo.example.combar.example.com 之间共享 Cookie,但不能在 example.comexample2 之间共享 Cookie。 com 这是出于安全原因。

There's no such thing as cross domain cookies. You could share a cookie between foo.example.com and bar.example.com but never between example.com and example2.com and that's for security reasons.

污味仙女 2024-09-18 22:59:48

最明智的解决方案是效仿 Facebook 的做法。当您访问任何域名时,Facebook 如何知道您是谁?它实际上非常简单

“赞”按钮实际上允许Facebook 跟踪外部网站的所有访问者,无论他们是否点击该网站。 Facebook 可以做到这一点,因为他们使用 iframe 来显示按钮。 iframe 类似于页面中的嵌入式浏览器窗口。使用 iframe 和按钮的简单图像之间的区别在于,iframe 包含一个完整的网页 - 来自 Facebook。除了按钮和有关有多少人喜欢当前页面的信息之外,此页面上没有太多内容。

因此,当您在 cnn.com 上看到“点赞”按钮时,您实际上是在同时访问 Facebook 页面。这使得 Facebook 能够读取您计算机上的 cookie,该 cookie 在您上次登录 Facebook 时创建。

每个浏览器的基本安全规则是只有创建 cookie 的网站才能稍后读取它。这就是 iframe 的优点:即使您正在访问不同的网站,它也允许 Facebook 读取您的 Facebook-cookie。这就是他们在 cnn.com 上识别您并在那里显示您的朋友的方式。

来源:

The smartest solution is to follow facebook's path on this. How does facebook know who you are when you visit any domain? It's actually very simple:

The Like button actually allows Facebook to track all visitors of the external site, no matter if they click it or not. Facebook can do that because they use an iframe to display the button. An iframe is something like an embedded browser window within a page. The difference between using an iframe and a simple image for the button is that the iframe contains a complete web page – from Facebook. There is not much going on on this page, except for the button and the information about how many people have liked the current page.

So when you see a like button on cnn.com, you are actually visiting a Facebook page at the same time. That allows Facebook to read a cookie on your computer, which it has created the last time you’ve logged in to Facebook.

A fundamental security rule in every browser is that only the website that has created a cookie can read it later on. And that is the advantage of the iframe: it allows Facebook to read your Facebook-cookie even when you are visiting a different website. That’s how they recognize you on cnn.com and display your friends there.

Source:

财迷小姐 2024-09-18 22:59:48

不允许跨域 cookie(即站点 A 无法在站点 B 上设置 cookie)。

但是一旦站点 A 设置了 cookie,您甚至可以在从站点 B 到站点 A 的请求中发送该 cookie (即跨域请求)

来自不同域的

XMLHttpRequest 无法为其自己的域设置 cookie 值,除非在发出请求之前将 withCredentials 设置为 true。通过将 withCredentials 设置为 true 获得的第三方 Cookie仍将遵循同源策略,因此请求脚本无法通过以下方式访问document.cookie 或来自响应标头。

确保执行以下操作:

  1. 在响应中设置 cookie 时
    • 如果请求是跨站点的,Set-Cookie 响应标头包含 SameSite=None(请注意来自 www 的请求) .example.devstatic.example.dev 实际上是一个同站点请求,并且可以使用 SameSite=Strict
    • 如果通过 HTTPS 提供服务,Set-Cookie 响应标头应包含 Secure 属性;如此处此处
  2. 发送/接收 cookie 时:
    • 请求是通过 withCredentials: true 发出的,如此处的其他答案中所述,并且此处包括响应设置的原始请求首先设置的 cookie
      • 对于fetch API,此属性为credentials: 'include'withCredentials: true
      • 对于 jQuery 的 ajax 方法,请注意您可能需要提供参数 crossDomain:正确
    • 服务器响应包含跨源标头例如 Access-Control-Allow-OriginAccess-Control-Allow-CredentialsAccess-Control-Allow-Headers访问控制允许方法
      • 正如 @nabrown 指出的:“请注意,如果您使用 ,“Access-Control-Allow-Origin”不能是通配符 (*) 值>withCredentials: true”(请参阅​​ @nabrown 的评论,其中解释了一种解决方法。
  3. 一般来说:
    • 您的浏览器尚未禁用第 3 方 Cookie。 (*见下文)

不需要的东西(只需使用上面的内容):

  1. Set-Cookie 中的domain 属性;您可以选择根域(即 a.example.com 可以设置域值为 example.com 的 cookie,但这不是必需的;cookie 仍将是发送到 a.example.com,即使是从 b.other-site.example.com 发送
  2. 为了使 Cookie 在 Chrome 开发工具的“应用程序”选项卡中可见; 如果 cookie HttpOnly 属性的值为 true,Chrome 不会在“应用程序”选项卡中显示 cookie 值(它应该显示在初始请求中设置时的cookie值,以及在后续响应中发送时的cookie值,其中withCredentials:true

请注意“path”和“site”之间的区别” 用于 Cookie 目的。“path”与安全相关;“site”与安全相关:

path

服务器可以设置 Path 属性在 Set-Cookie 中,但它似乎与安全无关:

请注意,path 旨在提高性能,而不是安全性。即使路径不匹配,具有相同来源的网页仍然可以通过 document.cookie 访问 cookie。

site

SameSite 属性,根据 example.dev 文章,可以限制或允许跨站点 cookie;但什么是“网站”?

准确理解此处“站点”的含义很有帮助。该网站是域名后缀和其前面的域名部分的组合。例如,www.example.dev 域是 example.dev 站点的一部分...

这意味着对 static.example.dev 的请求来自 www.example.dev 的 code> 是一个 sameSite 请求(URL 的唯一区别在于子域)。

公共后缀列表定义了这一点,所以
它不仅包括 .com 等顶级域名,还包括服务
就像github.io

这意味着从 my-project.github.ioyour-project.github.io 的请求是 aa 跨站点请求(这些URL位于不同的域,因为github.io是域后缀;域your-projectmy -project 不同;因此不同的站点)

这意味着公共后缀的左侧;是子域(但是子域是主机的一部分;请参阅此答案中的奖励回复)

  • wwwwww.example.dev 中的子域;与 static.example.dev 相同的站点
  • your-projectyour-project.github.io 中的域;单独的站点为 my-project.github.io

在此 URL https://www.example.com:8888/examples/index.html 中,记住以下部分

  • : “协议”:https://
    • “方案”:https
  • “端口”:8888
  • “域名”又名 location.hostnamewww.example.com
    • “域名后缀”又名“顶级域名”(TLD):com
    • “域”:示例
    • “子域名”:www(子域名可以是单级(如 www)或多级(类似于 foo.bar.example.com 中的 foo.bar
  • “站点”(如“跨站点”,如果另一个 URL 具有不同的“站点”值) :example.com
    • “站点”=“域名”+“域名后缀”= example.com
  • “路径”:/examples/index.html

有用链接:

小心;我正在 Chrome 隐身选项卡中测试我的功能;根据我的 chrome://settings/cookies;我的设置是“阻止第三个”隐身模式中的派对 cookie”,因此我无法在隐身模式中测试跨站点 cookie。)

浏览器打开 URL chrome://settings/cookies,这表明已设置“在隐身模式下阻止第三方 cookie”设置,选择“您浏览器中允许第三方 cookie 的设置

Cross-domain cookies are not allowed (i.e. site A cannot set a cookie on site B).

But once a cookie is set by site A, you can send that cookie even in requests from site B to site A (i.e. cross-domain requests):

XMLHttpRequest from a different domain cannot set cookie values for their own domain unless withCredentials is set to true before making the request. The third-party cookies obtained by setting withCredentials to true will still honor same-origin policy and hence can not be accessed by the requesting script through document.cookie or from response headers.

Make sure to do these things:

  1. When setting the cookie in a response
    • The Set-Cookie response header includes SameSite=None if the requests are cross-site (note a request from www.example.dev to static.example.dev is actually a same-site request, and can use SameSite=Strict)
    • The Set-Cookie response header should include the Secure attribute if served over HTTPS; as seen here and here
  2. When sending/receiving the cookie:
    • The request is made with withCredentials: true, as mentioned in other answers here and here, including the original request whose response sets the cookie set in the first place
      • For the fetch API, this attribute is credentials: 'include', vs withCredentials: true
      • For jQuery's ajax method, note you may need to supply argument crossDomain: true
    • The server response includes cross-origin headers like Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-Headers, and Access-Control-Allow-Methods
      • As @nabrown points out: "Note that the "Access-Control-Allow-Origin" cannot be the wildcard (*) value if you use the withCredentials: true" (see @nabrown's comment which explains one workaround for this.
  3. In general:
    • Your browser hasn't disabled 3rd-party cookies. (* see below)

Things that you don't need (just use the above):

  1. domain attribute in the Set-Cookie; you can choose a root domain (i.e. a.example.com can set a cookie with a domain value of example.com, but it's not necessary; the cookie will still be sent to a.example.com, even if sent from b.other-site.example.com
  2. For the cookie to be visible in Chrome Dev Tools, "Application" tab; if the value of cookie HttpOnly attribute is true, Chrome won't show you the cookie value in the Application tab (it should show the cookie value when set in the initial request, and sent in subsequent responses where withCredentials: true)

Notice the difference between "path" and "site" for Cookie purposes. "path" is not security-related; "site" is security-related:

path

Servers can set a Path attribute in the Set-Cookie, but it doesn't seem security related:

Note that path was intended for performance, not security. Web pages having the same origin still can access cookie via document.cookie even though the paths are mismatched.

site

The SameSite attribute, according to example.dev article, can restrict or allow cross-site cookies; but what is a "site"?

It's helpful to understand exactly what 'site' means here. The site is the combination of the domain suffix and the part of the domain just before it. For example, the www.example.dev domain is part of the example.dev site...

This means a request to static.example.dev from www.example.dev, is a sameSite request (the only difference in the URLs is in the subdomains).

The public suffix list defines this, so
it's not just top-level domains like .com but also includes services
like github.io

This means a request to your-project.github.io from my-project.github.io, is a a cross-site request (these URLs are at different domains, because github.io is the domain suffix; the domains your-project vs my-project are different; hence different sites)

This means what's to the left of the public suffix; is the subdomain (but the subdomain is a part of the host; see the BONUS reply in this answer)

  • www is the subdomain in www.example.dev; same site as static.example.dev
  • your-project is the domain in your-project.github.io; separate site as my-project.github.io

In this URL https://www.example.com:8888/examples/index.html, remember these parts:

  • the "protocol": https://
    • the "scheme": https
  • the "port": 8888
  • the "domain name" aka location.hostname: www.example.com
    • the "domain suffix" aka "top-level domain" (TLD): com
    • the "domain": example
    • the "subdomain": www (the subdomain could be single-level (like www) or multi-level (like foo.bar in foo.bar.example.com)
  • the "site" (as in "cross-site" if another URL had a different "site" value): example.com
    • "site" = "domain" + "domain suffix" = example.com
  • the "path": /examples/index.html

Useful links:

(Be careful; I was testing my feature in Chrome Incognito tab; according to my chrome://settings/cookies; my settings were "Block third party cookies in Incognito", so I can't test Cross-site cookies in Incognito.)

a browser is open to the URL chrome://settings/cookies, which shows that "Block third-party cookies in Incognito" setting is set, choose a setting in your browser that will allow third-party cookies

通知家属抬走 2024-09-18 22:59:48

您无法跨域共享 cookie。但是,您可以允许所有子域都有访问权限。要允许 example.com 的所有子域都具有访问权限,请将域设置为 .example.com

不过,不可能授予 other.example 访问 example.com cookie 的权限。

You cannot share cookies across domains. You can however allow all subdomains to have access. To allow all subdomains of example.com to have access, set the domain to .example.com.

It's not possible giving other.example access to example.com's cookies though.

兲鉂ぱ嘚淚 2024-09-18 22:59:48

做谷歌正在做的事情。创建一个 PHP 文件,在所有 3 个域上设置 cookie。然后在要设置主题的域上,创建一个 HTML 文件,该文件将加载在其他 2 个域上设置 cookie 的 PHP 文件。示例:

<html>
   <head></head>
   <body>
      <p>Please wait.....</p>
      <img src="http://domain2.example/setcookie.php?theme=whateveryourthemehere" />
      <img src="http://domain3.example/setcookie.php?theme=whateveryourthemehere" />
   </body>
</html>

然后在 body 标记上添加 onload 回调。仅当图像完全加载(即在其他 2 个域上设置 cookie)时,文档才会加载。 Onload 回调:

<head>
   <script>
   function loadComplete(){
      window.location="http://domain1.example";//URL of domain1
   }
   </script>
</head>
<body onload="loadComplete()">

setcookie.php

我们使用 PHP 文件在其他域上设置 cookie,如下所示:

<?php
if(isset($_GET['theme'])){
   setcookie("theme", $_GET['theme'], time()+3600);
}
?>

现在在三个域上设置了 cookie。

Do what Google is doing. Create a PHP file that sets the cookie on all 3 domains. Then on the domain where the theme is going to set, create a HTML file that would load the PHP file that sets cookie on the other 2 domains. Example:

<html>
   <head></head>
   <body>
      <p>Please wait.....</p>
      <img src="http://domain2.example/setcookie.php?theme=whateveryourthemehere" />
      <img src="http://domain3.example/setcookie.php?theme=whateveryourthemehere" />
   </body>
</html>

Then add an onload callback on body tag. The document will only load when the images completely load that is when cookies are set on the other 2 domains. Onload Callback:

<head>
   <script>
   function loadComplete(){
      window.location="http://domain1.example";//URL of domain1
   }
   </script>
</head>
<body onload="loadComplete()">

setcookie.php

We set the cookies on the other domains using a PHP file like this:

<?php
if(isset($_GET['theme'])){
   setcookie("theme", $_GET['theme'], time()+3600);
}
?>

Now cookies are set on the three domains.

何必那么矫情 2024-09-18 22:59:48

您可以尝试使用图像标签将 cookie val 推送到另一个域。

尝试执行此操作时,您的情况可能会有所不同,因为某些浏览器要求您在 WebApp2 域或浏览器上拥有适当的 P3P 策略将拒绝 cookie。

如果您查看 plus.google.com p3p 政策,您会发现他们的政策是:

CP="这不是 P3P 政策!请参阅 http://www.google.com/support/accounts/bin/answer.py?hl=zh-CN&answer=151657 了解详情。”

这是他们对这些跨域请求的 +1 按钮使用的策略。

另一个警告是,如果您使用 https,请确保图像标签指向 https 地址,否则 cookie 将不会设置。

You can attempt to push the cookie val to another domain using an image tag.

Your mileage may vary when trying to do this because some browsers require you to have a proper P3P Policy on the WebApp2 domain or the browser will reject the cookie.

If you look at plus.google.com p3p policy you will see that their policy is:

CP="This is not a P3P policy! See http://www.google.com/support/accounts/bin/answer.py?hl=en&answer=151657 for more info."

that is the policy they use for their +1 buttons to these cross domain requests.

Another warning is that if you are on https make sure that the image tag is pointing to an https address also otherwise the cookies will not set.

残月升风 2024-09-18 22:59:48

这里有一个关于 Facebook 如何使用的不错的概述在 nfriedly.com 上执行此操作

还有浏览器指纹识别,它与 cookie 不同,但具有相似的用途,因为它可以帮助您相当确定地识别用户。 Stack Overflow 上有一篇文章这里 引用了一种指纹识别方法

There's a decent overview of how Facebook does it here on nfriedly.com

There's also Browser Fingerprinting, which is not the same as a cookie, but serves a like purpose in that it helps you identify a user with a fair degree of certainty. There's a post here on Stack Overflow that references upon one method of fingerprinting

活雷疯 2024-09-18 22:59:48

人们可以使用不可见的 iframe 来获取 cookie。假设有两个域,a.exampleb.example。对于a.example域的index.html,可以添加(注意height=0 width=0):

<iframe height="0" id="iframe" src="http://b.example" width="0"></iframe>

这样您的网站将获得b.example< /code> cookie 假设 http://b.example 设置了 cookie。

接下来的事情是通过 JavaScript 操作 iframe 内的站点。如果不拥有第二个域,iframe 内的操作可能会成为一个挑战。但是,如果可以访问这两个域,则在 iframe 的 src 中引用正确的网页应该提供人们想要获取的 cookie。

One can use invisible iframes to get the cookies. Let's say there are two domains, a.example and b.example. For the index.html of domain a.example one can add (notice height=0 width=0):

<iframe height="0" id="iframe" src="http://b.example" width="0"></iframe>

That way your website will get b.example cookies assuming that http://b.example sets the cookies.

The next thing would be manipulating the site inside the iframe through JavaScript. The operations inside iframe may become a challenge if one doesn't own the second domain. But in case of having access to both domains referring the right web page at the src of iframe should give the cookies one would like to get.

强辩 2024-09-18 22:59:48

我创建了一个 NPM 模块,它允许您跨域共享本地存储的数据:
https://www.npmjs.com/package/cookie-toss

通过使用iframe 托管在域 A 上,您可以将所有用户数据存储在域 A 上,并通过向域 A iframe 发布请求来引用该数据。

因此,域 B、C 等可以注入 iframe 并向其发送请求以存储和访问所需的数据。域A成为所有共享数据的中心。

通过域 A 内部的域白名单,您可以确保只有您的依赖站点可以访问域 A 上的数据。

诀窍是让域 A 上的 iframe 内部的代码能够识别正在请求哪些数据。上述 NPM 模块中的 README 更深入地介绍了该过程。

希望这有帮助!

I've created an NPM module, which allows you to share locally-stored data across domains:
https://www.npmjs.com/package/cookie-toss

By using an iframe hosted on Domain A, you can store all of your user data on Domain A, and reference that data by posting requests to the Domain A iframe.

Thus, Domains B, C, etc. can inject the iframe and post requests to it to store and access the desired data. Domain A becomes the hub for all shared data.

With a domain whitelist inside of Domain A, you can ensure only your dependent sites can access the data on Domain A.

The trick is to have the code inside of the iframe on Domain A which is able to recognize which data is being requested. The README in the above NPM module goes more in depth into the procedure.

Hope this helps!

鲸落 2024-09-18 22:59:48

因为很难做到第 3 方 cookie,而且某些浏览器也不允许这样做。

您可以尝试将它们存储在 HTML5 本地存储中,然后随前端应用程序的每个请求一起发送它们。

Since it is difficult to do 3rd party cookies and also some browsers won't allow that.

You can try storing them in HTML5 local storage and then sending them with every request from your front end app.

帅哥哥的热头脑 2024-09-18 22:59:48

除了@Ludovic(批准的答案)答案之外,我们还需要在获取 set-cookies 标头时检查另一个选项,

set-cookie: SESSIONID=60B2E91C53B976B444144063; Path=/dev/api/abc; HttpOnly

即检查 Path 属性值。这应该与您的 API 启动上下文路径相同,如下所示

https://www.example.com/dev/api/abc/v1/users/123

,或者在不确定上下文路径时使用下面的值

Path=/;

Along with @Ludovic(approved answer) answers we need to check one more option when getting set-cookies header,

set-cookie: SESSIONID=60B2E91C53B976B444144063; Path=/dev/api/abc; HttpOnly

Check for Path attribute value also. This should be the same as your API starting context path like below

https://www.example.com/dev/api/abc/v1/users/123

or use below value when not sure about context path

Path=/;
枕梦 2024-09-18 22:59:48
function GetOrder(status, filter) {
    var isValid = true; //isValidGuid(customerId);
    if (isValid) {
        var refundhtmlstr = '';
        //varsURL = ApiPath + '/api/Orders/Customer/' + customerId + '?status=' + status + '&filter=' + filter;
        varsURL = ApiPath + '/api/Orders/Customer?status=' + status + '&filter=' + filter;
        $.ajax({
            type: "GET",
            //url: ApiPath + '/api/Orders/Customer/' + customerId + '?status=' + status + '&filter=' + filter,
            url: ApiPath + '/api/Orders/Customer?status=' + status + '&filter=' + filter,
            dataType: "json",
            crossDomain: true,
            xhrFields: {
                withCredentials: true
            },
            success: function (data) {
                var htmlStr = '';
                if (data == null || data.Count === 0) {
                    htmlStr = '<div class="card"><div class="card-header">Bu kriterlere uygun sipariş bulunamadı.</div></div>';
                }
                else {
                    $('#ReturnPolicyBtnUrl').attr('href', data.ReturnPolicyBtnUrl);
                    var groupedData = data.OrderDto.sort(function (x, y) {
                        return new Date(y.OrderDate) - new Date(x.OrderDate);
                    });
                    groupedData = _.groupBy(data.OrderDto, function (d) { return toMonthStr(d.OrderDate) });
                    localStorage['orderData'] = JSON.stringify(data.OrderDto);

                    $.each(groupedData, function (key, val) {

                        var sortedData = groupedData[key].sort(function (x, y) {
                            return new Date(y.OrderDate) - new Date(x.OrderDate);
                        });
                        htmlStr += '<div class="card-header">' + key + '</div>';
                        $.each(sortedData, function (keyitem, valitem) {
                            //Date Convertions
                            if (valitem.StatusDesc != null) {
                                valitem.StatusDesc = valitem.StatusDesc;
                            }

                            var date = valitem.OrderDate;
                            date = date.substring(0, 10).split('-');
                            date = date[2] + '.' + date[1] + '.' + date[0];
                            htmlStr += '<div class="col-lg-12 col-md-12 col-xs-12 col-sm-12 card-item clearfix ">' +
                        //'<div class="card-item-head"><span class="order-head">Sipariş No: <a href="ViewOrderDetails.html?CustomerId=' + customerId + '&OrderNo=' + valitem.OrderNumber + '" >' + valitem.OrderNumber + '</a></span><span class="order-date">' + date + '</span></div>' +
                        '<div class="card-item-head"><span class="order-head">Sipariş No: <a href="ViewOrderDetails.html?OrderNo=' + valitem.OrderNumber + '" >' + valitem.OrderNumber + '</a></span><span class="order-date">' + date + '</span></div>' +
                        '<div class="card-item-head-desc">' + valitem.StatusDesc + '</div>' +
                        '<div class="card-item-body">' +
                            '<div class="slider responsive">';
                            var i = 0;
                            $.each(valitem.ItemList, function (keylineitem, vallineitem) {
                                var imageUrl = vallineitem.ProductImageUrl.replace('{size}', 200);
                                htmlStr += '<div><img src="' + imageUrl + '" alt="' + vallineitem.ProductName + '"><span class="img-desc">' + ProductNameStr(vallineitem.ProductName) + '</span></div>';
                                i++;
                            });
                            htmlStr += '</div>' +
                        '</div>' +
                    '</div>';
                        });
                    });

                    $.each(data.OrderDto, function (key, value) {
                        if (value.IsSAPMigrationflag === true) {
                            refundhtmlstr = '<div class="notify-reason"><span class="note"><B>Notification : </B> Geçmiş siparişleriniz yükleniyor.  Lütfen kısa bir süre sonra tekrar kontrol ediniz. Teşekkürler. </span></div>';
                        }
                    });
                }
                $('#orders').html(htmlStr);
                $("#notification").html(refundhtmlstr);
                ApplySlide();
            },
            error: function () {
                console.log("System Failure");
            }
        });
    }
}

Web.config

包含 UI 来源并将允许凭据设置为 true

<httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://burada.com" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
function GetOrder(status, filter) {
    var isValid = true; //isValidGuid(customerId);
    if (isValid) {
        var refundhtmlstr = '';
        //varsURL = ApiPath + '/api/Orders/Customer/' + customerId + '?status=' + status + '&filter=' + filter;
        varsURL = ApiPath + '/api/Orders/Customer?status=' + status + '&filter=' + filter;
        $.ajax({
            type: "GET",
            //url: ApiPath + '/api/Orders/Customer/' + customerId + '?status=' + status + '&filter=' + filter,
            url: ApiPath + '/api/Orders/Customer?status=' + status + '&filter=' + filter,
            dataType: "json",
            crossDomain: true,
            xhrFields: {
                withCredentials: true
            },
            success: function (data) {
                var htmlStr = '';
                if (data == null || data.Count === 0) {
                    htmlStr = '<div class="card"><div class="card-header">Bu kriterlere uygun sipariş bulunamadı.</div></div>';
                }
                else {
                    $('#ReturnPolicyBtnUrl').attr('href', data.ReturnPolicyBtnUrl);
                    var groupedData = data.OrderDto.sort(function (x, y) {
                        return new Date(y.OrderDate) - new Date(x.OrderDate);
                    });
                    groupedData = _.groupBy(data.OrderDto, function (d) { return toMonthStr(d.OrderDate) });
                    localStorage['orderData'] = JSON.stringify(data.OrderDto);

                    $.each(groupedData, function (key, val) {

                        var sortedData = groupedData[key].sort(function (x, y) {
                            return new Date(y.OrderDate) - new Date(x.OrderDate);
                        });
                        htmlStr += '<div class="card-header">' + key + '</div>';
                        $.each(sortedData, function (keyitem, valitem) {
                            //Date Convertions
                            if (valitem.StatusDesc != null) {
                                valitem.StatusDesc = valitem.StatusDesc;
                            }

                            var date = valitem.OrderDate;
                            date = date.substring(0, 10).split('-');
                            date = date[2] + '.' + date[1] + '.' + date[0];
                            htmlStr += '<div class="col-lg-12 col-md-12 col-xs-12 col-sm-12 card-item clearfix ">' +
                        //'<div class="card-item-head"><span class="order-head">Sipariş No: <a href="ViewOrderDetails.html?CustomerId=' + customerId + '&OrderNo=' + valitem.OrderNumber + '" >' + valitem.OrderNumber + '</a></span><span class="order-date">' + date + '</span></div>' +
                        '<div class="card-item-head"><span class="order-head">Sipariş No: <a href="ViewOrderDetails.html?OrderNo=' + valitem.OrderNumber + '" >' + valitem.OrderNumber + '</a></span><span class="order-date">' + date + '</span></div>' +
                        '<div class="card-item-head-desc">' + valitem.StatusDesc + '</div>' +
                        '<div class="card-item-body">' +
                            '<div class="slider responsive">';
                            var i = 0;
                            $.each(valitem.ItemList, function (keylineitem, vallineitem) {
                                var imageUrl = vallineitem.ProductImageUrl.replace('{size}', 200);
                                htmlStr += '<div><img src="' + imageUrl + '" alt="' + vallineitem.ProductName + '"><span class="img-desc">' + ProductNameStr(vallineitem.ProductName) + '</span></div>';
                                i++;
                            });
                            htmlStr += '</div>' +
                        '</div>' +
                    '</div>';
                        });
                    });

                    $.each(data.OrderDto, function (key, value) {
                        if (value.IsSAPMigrationflag === true) {
                            refundhtmlstr = '<div class="notify-reason"><span class="note"><B>Notification : </B> Geçmiş siparişleriniz yükleniyor.  Lütfen kısa bir süre sonra tekrar kontrol ediniz. Teşekkürler. </span></div>';
                        }
                    });
                }
                $('#orders').html(htmlStr);
                $("#notification").html(refundhtmlstr);
                ApplySlide();
            },
            error: function () {
                console.log("System Failure");
            }
        });
    }
}

Web.config

Include UI origin and set Allow Credentials to true

<httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://burada.com" />
        <add name="Access-Control-Allow-Headers" value="Content-Type" />
        <add name="Access-Control-Allow-Methods" value="GET, POST, PUT, DELETE, OPTIONS" />
        <add name="Access-Control-Allow-Credentials" value="true" />
      </customHeaders>
    </httpProtocol>
断肠人 2024-09-18 22:59:48

三种主要的基于浏览器的存储

  1. 会话存储
  2. 本地存储
  3. cookie 存储

  • 安全 cookie - 加密网站使用它来提供保护,防止黑客的任何可能的威胁.

  • 访问 cookie - document.cookie。这意味着该 cookie 已公开,并且可以通过跨站点脚本进行利用。保存的cookie值可以通过浏览器控制台看到。

作为预防措施,您应该始终尝试使用 JavaScript 使客户端无法访问您的 cookie。

  • HTTPonly - 确保无法使用 JavaScript 代码访问 cookie。这是针对跨脚本攻击的最重要的保护形式。

  • 安全属性 - 确保浏览器拒绝 Cookie,除非通过 HTTPS 进行连接。

  • sameSite 属性提高了 Cookie 安全性并避免隐私泄露。

  • sameSite=Lax - 设置为 Lax (sameSite = Lax) 意味着仅当浏览器 URL 中的域与 cookie 的域匹配时才会设置 cookie,从而消除第三方的域。这将限制跨站点共享,甚至在同一发布者拥有的不同域之间也是如此。我们需要包含 SameSite=None 以避免 Lax 的新默认值:

注意:有一个规范草案要求当 SameSite 属性设置为“none”时,将 Secure 属性设置为 true。某些网络浏览器或其他客户端可能采用此规范。

  • 使用 include 作为 { withCredentials: true } 必须包含来自前端的请求的所有 cookie。
const data = { email: '[email protected]' , password: '1234' };
const response = await axios.post('www.yourapi.com/login', data , { withCredentials: true });
  • Cookie 只能通过安全的 HTTPS 连接接受。为了让它发挥作用,我们必须将 Web 应用程序迁移到 HTTPS。

在express.js

res.cookie('token', token, {
      maxAge: 1000 * 60 * 60 * 24, // would expire after (for 15 minutes  1000 * 60 * 15 ) 15 minutes
      httpOnly: true, // The cookie only accessible by the web server
      sameSite: 'none',
      secure: true, // Marks the cookie to be used with HTTPS only.
    });

参考1中,参考 2

Three main kinds of browser-based storage:

  1. session storage
  2. local storage
  3. cookie storage

  • Secure cookies - are used by encrypted websites to offer protection from any possible threats from a hacker.

  • access cookie - document.cookie. This means that this cookie is exposed and can be exploited through cross-site scripting. The saved cookie values can be seen through the browser console.

As a precaution, you should always try to make your cookies inaccessible on the client-side using JavaScript.

  • HTTPonly - ensures that a cookie is not accessible using the JavaScript code. This is the most crucial form of protection against cross-scripting attacks.

  • A secure attribute - ensures that the browser will reject cookies unless the connection happens over HTTPS.

  • sameSite attribute improves cookie security and avoids privacy leaks.

  • sameSite=Lax - It is set to Lax (sameSite = Lax) meaning a cookie is only set when the domain in the URL of the browser matches the domain of the cookie, thus eliminating third party’s domains. This will restrict cross-site sharing even between different domains that the same publisher owns. we need to include SameSite=None to avoid the new default of Lax:

Note: There is a draft spec that requires that the Secure attribute be set to true when the SameSite attribute has been set to 'none'. Some web browsers or other clients may be adopting this specification.

  • Using includes as { withCredentials: true } must include all the cookies with the request from the front end.
const data = { email: '[email protected]' , password: '1234' };
const response = await axios.post('www.yourapi.com/login', data , { withCredentials: true });
  • Cookie should only be accepted over a secure HTTPS connection. In order to get this to work, we must move the web application to HTTPS.

In express.js

res.cookie('token', token, {
      maxAge: 1000 * 60 * 60 * 24, // would expire after (for 15 minutes  1000 * 60 * 15 ) 15 minutes
      httpOnly: true, // The cookie only accessible by the web server
      sameSite: 'none',
      secure: true, // Marks the cookie to be used with HTTPS only.
    });

Reference 1, Reference 2

娇女薄笑 2024-09-18 22:59:48

读取 Web Api 中的 Cookie

var cookie = actionContext.Request.Headers.GetCookies("newhbsslv1");


                    Logger.Log("Cookie  " + cookie, LoggerLevel.Info);
                    Logger.Log("Cookie count  " + cookie.Count, LoggerLevel.Info);

                    if (cookie != null && cookie.Count > 0)
                    {
                        Logger.Log("Befor For  " , LoggerLevel.Info);
                        foreach (var perCookie in cookie[0].Cookies)
                        {
                            Logger.Log("perCookie  " + perCookie, LoggerLevel.Info);

                            if (perCookie.Name == "newhbsslv1")
                            {
                                strToken = perCookie.Value;
                            }
                        }
                    }

Read Cookie in Web Api

var cookie = actionContext.Request.Headers.GetCookies("newhbsslv1");


                    Logger.Log("Cookie  " + cookie, LoggerLevel.Info);
                    Logger.Log("Cookie count  " + cookie.Count, LoggerLevel.Info);

                    if (cookie != null && cookie.Count > 0)
                    {
                        Logger.Log("Befor For  " , LoggerLevel.Info);
                        foreach (var perCookie in cookie[0].Cookies)
                        {
                            Logger.Log("perCookie  " + perCookie, LoggerLevel.Info);

                            if (perCookie.Name == "newhbsslv1")
                            {
                                strToken = perCookie.Value;
                            }
                        }
                    }
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文