Safari browser not keeping my cookie in memory - cookies

On my website, I'm using a http only cookie to do the authentification. It works perfectly in all browser, except Safari. Whenever the app close and reopen, it changes the cookie value to new_value.
Here's how the cookie is setup using the response object from express:
response.cookie('authToken', authToken, {
expires: date, // date 5 days from now
sameSite: 'strict',
httpOnly: true,
secure: true
});

Related

Session cookie is not getting saved from Pantheon

We are working on log in functionality with headless React and Pantheon with REST web services.
When I send login request to Drupal site in localhost, it sets a session cookie in my browser.
However, it doesn't do that for Drupal site deployed to Pantheon.
The cookie:
set-cookie: SSESS4ca8b3ff629fc50c99bed7678686=VYfXzM-S18y0n8PylU9HuHBVrEyZezRiwfirxB%2ClL; expires=Fri, 18-Nov-2022 18:14:03 GMT; Max-Age=2000000; path=/; domain=.oursitename.pantheonsite.io; secure; HttpOnly
Login request:
const body = {
name: name,
pass: pass,
};
const config = {
headers: {
"Content-Type": "application/json",
"X-CSRF-Token": token,
},
withCredentials: true,
};
axios
.post(
`${process.env.REACT_APP_DRUPAL_URL}/user/login?_format=json`,
body,
config
)
Update:
Cookie is getting stored in Mozilla browser, but not in Chrome.
You need to append STYXKEY to the cookie's name. Cookies without that prefix are stripped from the request at the edge in Pantheon
You may find interesting as well this official documentation about pantheon and cookies
https://pantheon.io/docs/cookies

Not able to set cookie in browser with Deno Oak

I am trying to set up Authentication with Deno, Oak and JWT.
Objective:
Send cookie with jwt token in the response.
Set cookie in the browser
Use the cookie for subsequent requests.
Route: Cookie being set
export const getUsers = async ({ response, cookies }) => {
const users = await userCollection.find().toArray();
await cookies.set("token", "1234567890", {
sameSite: "lax",
});
response.body = users;
};
handling the Cors issue
app.use(
oakCors({
credentials: true,
origin: /^.+localhost:(3000|4200|8080)$/,
})
);
Response headers has the cookie but the same is not set in Application --> Cookies.
Please help me understand this issue.
using ctx.cookies.set is how you set a cookie in Oak, have in mind that by default it's httpOnly. Your browser might not show it in that case or you're looking in the wrong place.
From the screenshot we can see that Oak is setting the cookie correctly in the response headers:
token=1234567890; path=/; samesite=lax; httponly
To check that the cookie is set correctly, just add:
console.log(await ctx.cookies.get('token'));
And you'll see that in subsequent requests will log 1234567890 correctly.
Since you're mentioning CORS I suspect that you're looking the cookie to be present in the wrong domain, you should be looking for the cookie in:
localhost:8000 (server setting the cookie)
And not in your front end domain:port
So, if you issue the request from: http://localhost:3000 to http://localhost:8000, when you're in :3000 there will be no cookie present in Application > Cookies > http://localhost:3000, but it'll be in Application > Cookies > http://localhost:8000

Firefox not sending all Cross-Site cookies dispite CORS setup working in Chrome

I have various country domains which I wish to share cookie data with the primary domain, ie for auth purposes so that users remain logged in or identified when transitioning between these domains.
All is working as expected in Chrome, however Firefox is refusing to send non-session cookies along with cross-site requests. (session cookies are being included successfully). There are no warnings or errors within the firefox console relating to this.
When a cookie is set on the primary domain, I am setting SameSite to none and secure to true:
set-cookie: nonsessioncookie=abc1234; expires=Sun, 03-Sep-2023 13:36:26 GMT; path=/; SameSite=none; secure=true;
I then perform a jQuery request from a secondary domain to the primary domain:
$.ajax({
url: primaryHost + "/Services/AuthRequest.ashx",
data: { 'sdtoken': stoken},
xhrFields: {
withCredentials: true
},
crossDomain: true,
success: function (data) {
// Do Something
}
});
The following Request headers are sent, however notice the only cookie being sent is a session cookie; the 'nonsessioncookie' cookie is missing from the request:
Origin: https://secondary.domain
Connection: keep-alive
Referer: https://secondary.domain/
Cookie: ASP.NET_SessionId=rpchfdrzqzp5zujwi24fjll2
Sec-Fetch-Dest: empty
Sec-Fetch-Mode: cors
Sec-Fetch-Site: cross-site
And the Response contains the following headers returned from the primary domain
access-control-allow-origin: https://secondary.domain
access-control-allow-methods: POST, GET, OPTIONS
access-control-allow-credentials: true
Chrome successfully passes the 'nonsessioncookie', however firefox doesn't, even though SameSite and secure is set.
Any thoughts what could be preventing non-session cookies from being passed?

CSRF not working in django with safari private browsing

I am unable to POST data to my django webapp in safari private browsing (it works with Chrome incognito).
I am not using localstorage.
I set the X-CSRFToken header using
var csrftoken = NMA.getCookie('csrftoken');
$.ajax({
type:"POST",
contentType: 'application/json; charset=utf-8',
beforeSend: function (request, settings) {
if (!csrfSafeMethod(settings.type) && !this.crossDomain){
request.setRequestHeader("X-CSRFToken", csrftoken);
}
},
url: "/profiler/logAnswers/
data: payload,
dataType: 'json'
}).done(...
The csrftoken cookie is set using {% csrf_token %} and the hidden input is present inside the <form>
I have inspected the request using charles and the csrftoken cookie is set and the X-CSRFToken header is set.
I have noticed that safari in private browsing adds "DNT = 1" (do not track) to the header, not sure if this is causing the problem. The DNT=1 is not present in chrome incognito requests.
I have logged the cookies in
python2.7/site-packages/django/middleware/csrf.py
using
logger.debug(request.COOKIES)
and the csrftoken cookie is missing (and several other cookies are missing). There are only 4 cookies printed. There are 13 cookies present in the initial request as seen in charles.
As there is no csrftoken this causes the
Forbidden (CSRF cookie not set.) 403 error.
What does the DNT=1 in the header do? Does it limit the number of cookies allowed? Does it prevent certain types of cookies?
Problem was that (in order to get around localstorage not being available) I have json objects saved in cookies. There is a python bug or issue:
https://bugs.python.org/issue27674
that causes only some of the cookies to be decoded if there are any quotation marks in the string.
So solution is to replace the quotation marks in all of the cookies

Accessing cookie with Angular or Javascript

I created an API /user/auth where I can send using POST a Json object like:
var user = {"username":"alex", "password":"m"}
$http(
{
method: 'POST',
url: '/api/v1/user/auth',
data: user,
}
).
success(function(data, status, headers, config) {
console.log(data)
}).
error(function(data, status, headers, config) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
The response from Django is the following:
Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Content-Type,*
Access-Control-Allow-Methods:POST,GET,OPTIONS,PUT,DELETE
Access-Control-Allow-Origin:*
Content-Language:fr
Content-Type:application/json
Date:Fri, 30 Aug 2013 15:22:01 GMT
Server:WSGIServer/0.1 Python/2.7.5
Set-Cookie:sessionid=w63m0aoo8m3vfmvv0vk5d6w1708ftsrk; Path=/
Vary:Accept, Accept-Language, Cookie
So Django returns a good cookie but I don't know why, Chrome doesn't set this cookie in Resource.
The request is sent from 127.0.0.1:8000 to 127.0.0.1:8080; I use this middleware to handle CROS requests and I also set:
SESSION_COOKIE_HTTPONLY = False
The problematic line is:
Access-Control-Allow-Origin: *
The credential request doesn't work with a wildcard allow origin. You have to specifically set the name, like :
Access-Control-Allow-Origin: http://127.0.0.1:8080
You can find more information here:
https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control#Requests_with_credentials
Ok thanks to Bqm link to mozilla I finally found why the cookie was not set.
Indeed you need to set in the header you sent:
Access-Control-Allow-Credentials: true
In Angular this is done with this method:
$http(
{
method: 'POST',
url: '/api/v1/user/auth',
data: user,
withCredentials: true
}
)
Once your backend will answer with a setCookie, the browser will then be able to set the cookie in your browser.