Here and there I get stuck. Like last time, I was writing an authentication using tokens and httpOnly cookies (will write a dedicated article about it in the near future). Basically the backend is instantiating a httpOnly cookie with a session id in it and send it to the frontend. Frontend should send such cookie back with each request and the backend can read the token from the cookies and verify it.
So far, so good, unless you use the
load method (loading in docs) and the request is sent not by the client, but by the SvelteKit server in pre-render. In such case the cookies must be passed to the SvelteKit server first, in order to be sent with the request to the API.
Basically there are proposed solutions:
1) use handle hook and read the token from cookies in the backend (handle method is run on every request before the component is created), pass it to the frontend to the
load method and use it with the fetch from there. The thing is you are exposing the token to the client and it is a big security vulnerability.
It is even stated in the docs:
In the load method you:
should not directly reference any API keys or secrets, which will be exposed to the client, but instead call an endpoint that uses any required secret
2) Which is leading to the second workaround - use the SvelteKit endpoint as a proxy (do not mistake it with the backend API endpoint. This endpoint is part of your SvelteKit frontend application). To pass every request to the endpoint first, enrich the request with the cookies or token in headers and then, finally, make a request to the backend api. You can even make such endpoint generic (and proxy all your app request through this single endpoint), but it could possibly be kind of a bottleneck and I just simply don't want this proxy in my frontend app.
I was still hoping for a better solution, the correct one.
In SvelteKit documentation there is stated a small discreet note:
Cookies will only be passed through if the target host is the same as the SvelteKit application or a more specific subdomain of it.
Which means we have to get rid of localhost with port (
localhost:####) urls and use proper domains. Locally.
I'm using Docker for a local development anyway, so some reverse proxy image was an easy choise.
The idea was simple - according to the SvelteKit docs quote above the frontend and the backend must be run on the same domain (not possible), or the frontend can run on a domain
dev.localhost and the api on a subdomain
It is also a premise for cookies to be exchanged between the frontend and the backend (the backend and frontend must share the same 2nd level domain).
If you are just keen for the solution, here is the
version: "3.4" services: proxy: container_name: proxy.dev.localhost image: jwilder/nginx-proxy network_mode: bridge ports: - "80:80" volumes: - /var/run/docker.sock:/tmp/docker.sock:ro networks: - myNetwork frontend: container_name: dev.localhost image: node:lts working_dir: /var/www/html/app/ entrypoint: /bin/bash environment: - HOST=0.0.0.0 - VIRTUAL_HOST=dev.localhost - VIRTUAL_PORT=80 expose: - 80 - 10000 - 35729 volumes: - ./frontend/:/var/www/html/app tty: true networks: - myNetwork backend: container_name: be.dev.localhost image: node:lts working_dir: /var/www/html/app/ entrypoint: /bin/bash environment: - VIRTUAL_HOST=be.dev.localhost expose: - 80 volumes: - ./backend/:/var/www/html/app tty: true networks: - myNetwork database: container_name: db.dev.localhost image: mongo:4.4.10 environment: - VIRTUAL_HOST=db.dev.localhost ports: - 27017:27017 volumes: - mongodata:/data/db networks: - myNetwork networks: myNetwork: external: true volumes: mongodata: external: true
Important to note is:
You must also put these domains to the HOSTS file:
127.0.0.1 dev.localhost be.dev.localhost db.dev.localhost
On Windows 10 the hosts file is on the path
There is a way how to setup the dev environment using Docker to simulate a production domain setup on local computer. In such setup you can use httpOnly cookies authentication without any security leaks made just because of the compromises for the local development.