13

I have a website which requires authentication from another site to login. Both are different domains.

I have enabled the samesite by default cookies flag from chrome://flags. Just to check how chrome's new update effects in my website.

It is working perfectly in my deployed site. But when i try to run the same in my localhost, I am not able to login. I lost my third-party cookies.

It would be great, if someone explains the reason.

Invisible Coder
  • 139
  • 1
  • 1
  • 4

4 Answers4

10

Unfortunately all cookies with SameSite=None must have a Secure parameter as well. Since you are unlikely to run HTTPS on your development server, this means your cookies won't work because the cookies are not sent over HTTPS.

The only workaround I am currently aware of is to check your environment, and set the cookies with SameSite=Lax for your development environment, and to SameSite=None; Secure for production.

In Express, you could use the secure parameter to check if you are running on HTTPS, and then set your cookie as follows:

const {secure} = req;
res.cookie('key', 'contents', {
  secure,
  httpOnly: true,
  sameSite: secure ? 'None' : 'Lax',
});
Adam Reis
  • 4,165
  • 1
  • 44
  • 35
  • According to MDN, it should still work on localhost: https://developer.mozilla.org/en-US/docs/Web/HTTP/Cookies "It's never sent with unsecured HTTP (except on localhost)" – Herobrine Jul 14 '22 at 14:26
  • 1
    Tested this on localhost on v91 of chrome and does not work – Bersan Nov 11 '22 at 22:10
1

As you know for the cross-site cookies we have to specify the attribute SameSite=None and Secure. Assuming you don't have an SSL certificate on your localhost the reason it stopped working is that only the cookies sent over HTTPS may use the Secure attribute.

Dharman
  • 30,962
  • 25
  • 85
  • 135
1

I came across this problem and there's no simple way to solve this problem except relying on the fact that I must use HTTPS if I working with API that uses SameSite: None.

So then I created a software to solve this problem.

npx secure-localhost 3000

That will proxy all https://localhost requests to http://localhost:3000. Be warned that this software automatically generates and installs a self-signed certificate on Windows at the current user level (it only works for Windows currently).

willnode
  • 1,377
  • 13
  • 17
1

You can create and use a reverse proxy to solve this.

Create a folder and make a file named

nginx.conf

server {
    listen       8080;
    server_name  yourapp-gateway-service api.yourapp.co;
    
    error_page  404              /404.html;
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    location / {
        proxy_pass https://api.yourapp.com/;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Scheme $scheme;
        proxy_ssl_server_name on;
        client_max_body_size 50M;
    }
}

create a docker image

Dockerfile

FROM nginx:1.17
ADD nginx.conf /etc/nginx/conf.d/default.conf
EXPOSE 8080
ENTRYPOINT ["nginx", "-g", "daemon off;"]

You can now build and push your container to a registry or just use it as is. I use gitlab and my gitlab-ci.yaml looks like this

image: docker:latest
services:
  - docker:dind

stages:
- package

variables:
  DOCKER_DRIVER: overlay
  CONTAINER_IMAGE: registry.gitlab.com/MYGROUP/projects/MYPROJECT-gateway:${CI_COMMIT_SHORT_SHA}
  CONTAINER_IMAGE_LATEST: registry.gitlab.com/MYGROUP/projects/MYPROJECT-gateway:LATEST

docker-build:
  stage: package
  script:
    - docker build -t ${CONTAINER_IMAGE} .
    - docker login -u gitlab-ci-token -p $CI_BUILD_TOKEN registry.gitlab.com
    - docker tag ${CONTAINER_IMAGE} ${CONTAINER_IMAGE}
    - docker tag ${CONTAINER_IMAGE} ${CONTAINER_IMAGE_LATEST}
    - docker push ${CONTAINER_IMAGE}
    - docker push ${CONTAINER_IMAGE_LATEST}
Çağdaş Tunca
  • 873
  • 1
  • 11
  • 24