345

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

shA.t
  • 16,580
  • 5
  • 54
  • 111
SundarJavaDeveloper
  • 3,531
  • 3
  • 17
  • 11

17 Answers17

174

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
}
Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Ludovic
  • 1,757
  • 1
  • 10
  • 2
  • 7
    Or if you are not wanting to filter on origin, just use $_SERVER['HTTP_ORIGIN'] instead of * – Joel Teply Apr 29 '15 at 16:22
  • 1
    This is the only things that worked for me. Also, * was not accepted as origin, so @Joel Teply's tip is needed. – Guessed Sep 27 '15 at 20:14
  • 1
    It worked perfectly when I run the code on localhost, but at runtime I don't see the cookies being set to the API and I get a 401 (unauthorized) error as expected. any ideas? – Heba Gomaah Oct 14 '15 at 13:17
  • 12
    This won't work if third-party cookies are disabled (automatic for some browser situations). See https://blog.zok.pw/web/2015/10/21/3rd-party-cookies-in-practice/ and http://www.allannienhuis.com/archives/2013/11/03/blocked-3rd-party-session-cookies-in-iframes/ for more information. – robocat Feb 24 '16 at 04:12
  • 11
    Don't use Joel's tip, because it is "in essence" the same as setting it to "*" which can open up subtle security holes so is discouraged, see http://stackoverflow.com/questions/12001269/what-are-the-security-risks-of-setting-access-control-allow-origin – rogerdpack Apr 14 '17 at 18:50
  • 10
    on the server side of which domain? – Nick Manning Feb 22 '18 at 22:48
  • 3
    somebody please accept this as a valid answer! It answers the question but it is not complete. It also needs to mention that the cookie has to have `SameSite:none; secure` like stated in this answer: https://stackoverflow.com/a/63728389/985942 – avepr May 11 '21 at 06:33
  • 1
    There is no `crossDomain` field in [XMLHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest) – belkka Jun 01 '21 at 09:03
  • 1
    @belkka I guess the answer assumes [`jQuery`](https://api.jquery.com/jQuery.ajax/). – x-yuri Jan 08 '22 at 16:53
  • It looks like in order to make it work from localhost the credentials value is not enough, maybe also you need to set up `SameSite:none;` in your server – josue.0 Jan 26 '22 at 15:41
  • This answer works but has no explanation what's going on, and explaining "domain2.com can **get** the cookie from domain1.com" is incorrect (for example JavaScript cannot get the cookie value). See the answer below https://stackoverflow.com/a/63728389/5267751 for better explanation. – user202729 May 21 '22 at 17:28
151

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.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
alcuadrado
  • 8,340
  • 3
  • 24
  • 25
  • 46
    If there is no other way, then how does StackExchange/OpenID work? – Hawken Oct 26 '12 at 21:30
  • 77
    @Hawken StackExchange/OpenID follows the same process as described above. You are directed to a different site (SO > SX), confirm your identity, and then are directed back to SO with the information you need. [The OpenID Spec](http://openid.net/developers/specs/) explains more, although [Wikipedia does it more plainly](http://en.wikipedia.org/wiki/OpenID#Logging_in). – Nick Q. Sep 30 '13 at 22:42
  • @alcuadrado How can you identify different users with this solution? Let say a user from a.com logged in and you set the information needed. Now when user go to b.com that uses same same script/application/plug-in how will you know that is the same user? – Olcay Ertaş Jul 03 '15 at 08:24
  • 2
    All users are logged in in cookiemaker.com actually. And it redirects the user to the different sites with a special and secure message that verifies that they are logged in and who they are. How to implement it is up to you, there are infinite ways of doing so. Maybe you can use this: http://jwt.io/ – alcuadrado Jul 10 '15 at 12:14
  • @nickq This isn't unique to OpenID, SAML2 implementations conceptually work in pretty much the same way. – Phil Lello Apr 10 '16 at 10:25
  • 23
    @Andrew_1510 `cookiebaker` would be better ;-) – Richard Turner May 12 '16 at 09:16
  • 1
    @alcuadrado, could you please explain a bit more detailed: 1) how cookiemaker knows where to redirect user after he is authenticated? Should origin-url come in querystring? 2) How "information you need" is passed to example.com while redirecting to it at step 3? – Sasha Oct 10 '16 at 16:46
  • Both have almost the same answer. 1) You redirect to something like cookimaker.com?redirection=yoursite.com 2) also as a query string parameter – alcuadrado Oct 11 '16 at 05:52
  • 1
    [Here](http://stackoverflow.com/a/19546680/2218697) is post with image tag , is that a **better solution** ? – Shaiju T Dec 13 '16 at 09:35
  • @Sasha If it's not too late (I bet it is), you should look into OpenID Connect – Hritik Nov 10 '21 at 06:30
83

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

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Vitae Aliquam
  • 1,024
  • 9
  • 7
  • 14
    This wont work for some users because CORS cookies will not work if third-party cookies are disabled e.g. [Safari by default](http://blog.prowebsoftware.net/2013/08/safari-cors-requests-withcredentials/) e.g. [Mozilla settings](http://www.goeszen.com/how-to-get-cookies-working-with-cors-jquery-and-xhr-ajax.html). Google [more examples](https://www.google.com/#q=withCredentials+third-party-cookies) and an [article about why Facebook](http://www.nfriedly.com/techblog/2010/08/how-facebook-sets-and-uses-cross-domain-cookies/) doesn't use third party cookies. – robocat Feb 24 '16 at 03:36
  • 1
    Does stack exchange / openID use CORS? – RayLoveless Jun 24 '16 at 20:01
  • 1
    FWIW I just tested a normal CORS withCredentials XHR and it worked on FF/Safari/Chrome...though I wouldn't doubt that facebook/google use more sophisticated schemes – rogerdpack Apr 14 '17 at 19:11
  • 1
    Is this a full solution for sharing an auth cookie between domain1.com and domain2.com? If so why do other posts say this is impossible? – John Little Mar 16 '23 at 12:55
58

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.

Washington Guedes
  • 4,254
  • 3
  • 30
  • 56
Darin Dimitrov
  • 1,023,142
  • 271
  • 3,287
  • 2,928
  • 3
    Hi thanks for the reply, can u please add more clarity on configuration part, how to create/configure domain and subdomain in j2ee environment??? – SundarJavaDeveloper Jul 27 '10 at 11:29
  • 2
    This is a question that is more adapted to http://serverfault.com where you will get answers from experts in the domain. – Darin Dimitrov Jul 27 '10 at 11:36
  • Hi, I tried having two webapps WebApp.domain.com ==> here i add cookie in respose as follows: Cookie cookie = new Cookie("namedCookie","test"); cookie.setDomain(".domain.com"); response.addCookie(cookie); WebApp1.domain.com==>Here i tried to access the cookie as follows, but cant able to access Cookie[]cks = request.getCookies(); for(int i=0;i – SundarJavaDeveloper Jul 28 '10 at 07:01
  • 2
    often repeated but not true, see my answer below or here http://stackoverflow.com/questions/16186645/cross-domain-cookies-a-maybe-new-idea – Raphael Jeger Apr 24 '13 at 12:31
  • Yes there is. You just need to use CORS. – Anoyz Apr 30 '15 at 16:40
  • 15
    How to share cookies between `foo.example.com` and `bar.example.com`? – Jeff Tian Aug 18 '16 at 07:43
  • [Here](http://stackoverflow.com/a/19546680/2218697) is post with image tag , is that a **better solution** for asp mvc ? – Shaiju T Dec 13 '16 at 09:36
  • "never" here is a bit misleading since you can access through CORS and "use 2 cookies" at the same time on the same page, as it were...which is almost like sharing them :) – rogerdpack Apr 14 '17 at 18:51
  • @JeffTian https://stackoverflow.com/questions/18492576/share-cookie-between-subdomain-and-domain here is explanation – piotrekkr Jul 23 '21 at 10:43
53

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:

Morteza Shahriari Nia
  • 1,392
  • 18
  • 24
  • 13
    I think an iframe would rarely classify as the best or the smartest way to do anything.. but it is the easiest. – Orun Jul 25 '18 at 15:57
  • Wouldn't the cookie from facebook be recognized as a third party cookie?! – Sebi2020 Sep 25 '21 at 13:13
  • 1
    Facebook domain will not have access to the parent window cookies, the most it can get is `window.parent.location` if they want, but it really doesn't matter because the parent window consciously choose to add the facebook-iframe, it means that on loading-time facebook already knows the parent page identifier. Basically, the parent page wants the facebook track-ability function. On the user side, to block it, it is needed some browser-extension to block undesired domains, like uBlock origin for Chrome. – Washington Guedes Sep 25 '21 at 16:26
47

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

Nate Anderson
  • 18,334
  • 18
  • 100
  • 135
  • 5
    This aren't cross-domain cookies. There is nothing like cross-domain cookies. It's a strict rule you cannot avoid. Page A can never set a cookie for Page B. You're just sending Cookies created by Page B on requests for Page B originating from Page A. – Sebi2020 Sep 25 '21 at 13:16
  • OK thanks @Sebi2020 I updated the answer I hope I captured the difference – Nate Anderson Sep 27 '21 at 17:37
  • 2
    This answer is clear, thorough and helpful. Note that the "Access-Control-Allow-Origin" cannot be the wildcard (*) value if you want to use the credentials option (`withCredentials` for XMLHttpRequest, or `credentials` for Fetch API). [MDN explanation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS/Errors/CORSNotSupportingCredentials). On the server, you'll have to grab the origin from incoming requests, and return that value in the "Access-Control-Allow-Origin" header. Whether this is a good or bad idea security-wise, I don't know. – nabrown Dec 10 '21 at 17:36
  • 1
    So if the UI app at app1.apps.space.pool.gap.mycompany.net sends a cookie to app2.apps.space.pool.gap.mycompany.net, would that be same-site or cross-site ? – copenndthagen May 27 '22 at 15:36
  • Hi @copenndthagen , I think that is `same-site` request; both of your URLs are at the same "site" of `mycompany.net`; the same domain and domain suffix. The only difference in your URLs is the subdomain. But that's **still** same site, as in the example: "This means a request to static.example.dev from www.example.dev, is a sameSite request." – Nate Anderson Sep 08 '22 at 19:26
  • @copenndthagen I think , even though your subdomain is ["multi-level"](https://webmasters.stackexchange.com/a/56985/78688), and very long, still the only difference is found in the subdomains: `app1.apps.space.pool.gap` and `app2.apps.space.pool.gap` (remember, `mycompany.net` is the site; consisting of the domain `mycompany` and the domain suffix `net`. Therefore everything "to the left" of `mycompany.next` in your URLs is the subdomain) – Nate Anderson Sep 08 '22 at 19:57
20

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.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Daniel Egeberg
  • 8,359
  • 31
  • 44
11

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.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Hossain Khademian
  • 1,616
  • 3
  • 19
  • 29
  • 3
    This doesn't work if the 'Block third party cookies' feature is enabled. – Jens Jul 25 '16 at 18:18
  • 2
    Just a copy-paste of [another answer to another question](https://stackoverflow.com/a/19546680/7710928). There is no "three domains" in this question. – belkka Jun 01 '21 at 09:22
  • This won't work on safari either... third party cookies are being deprecated everywhere. – Danny Dulai Aug 05 '22 at 20:37
8

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.

Bryan Focht
  • 1,004
  • 1
  • 11
  • 10
5

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

Community
  • 1
  • 1
byZero
  • 151
  • 2
  • 3
1

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.

Stephen Ostermiller
  • 23,933
  • 14
  • 88
  • 109
Vadym Tyemirov
  • 8,288
  • 4
  • 42
  • 38
  • 5
    Just a warning: There are some serious issues with cookies in iframes on Safari. They apparently don't work cross domain. – mvds Dec 04 '13 at 11:23
1

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!

jmealy
  • 583
  • 1
  • 5
  • 14
1

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.

Baraja Swargiary
  • 381
  • 2
  • 10
  • I agree. You can configure everything posted in the answers here, but if [third-party cookies](https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies#third-party_cookies) are disabled in the browser settings nothing will work. This is a privacy measure to prevent tracking. – Jules Jan 26 '23 at 10:02
0
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>
danronmoon
  • 3,814
  • 5
  • 34
  • 56
0

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=/;
sharad jain
  • 1,471
  • 13
  • 9
0

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: 'youremailaddress@gmail.com' , 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

Md Shayon
  • 79
  • 5
-4

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;
                            }
                        }
                    }
VVN
  • 1,607
  • 2
  • 16
  • 25