My setup is a SvelteKit app paired with an Express server (in order to handle sockets). This app has some POST requests which work fine with Vite, but not when I run it with Express. I get the error Cross-site POST form submissions are forbidden with a status code of 403 and a referrer policy "strict-origin-when-cross-origin".
So my question is very similar to this one, but the answers there didn't work for me (except for the insecure option to allow csrf). I also checked the SvelteKit documentation on the node adapter without success.
What I have tried:
ORIGIN=http://localhost:3000 node build/index.js
to my .env file. I also added dotenv
as a dependency and added dotenv.config()
to my server file. But this has no effect.csrf: {checkOrigin: false}
in svelte.config.js
fixed the issue, but this is not secure and not recommended.node -r dotenv/config build
in the terminal. This prints out "Listening on 0.0.0.0:3000"
. But then my express server does not start at all. Perhaps the command needs to be added to the package.json
, but I do not know where. There is no node build
in the file.node -r dotenv/config server.js
and open localhost:3000, I just get Invalid request body (code 400).It sure is frustrating to setup websockets with SvelteKit, even after reading this blog post.
server.ts:
import express from "express";
import { handler } from "./build/handler.js";
import { attach_sockets } from "./sockets.js";
import dotenv from "dotenv";
dotenv.config();
const PORT = 3000;
const app = express();
const server = app.listen(PORT, () => {
console.log("server is listening on port", PORT);
});
app.use(handler);
attach_sockets(server);
I've taken a look at your code and I have good and bad news... the good news is that you did nothing wrong. The bad news is that you can't get it working because of the way SvelteKit and NodeJS works (at least not in the intended way).
Let me elaborate:
From running your code, it is clear that the dotenv does not have any effect. Why is that? Quite simply, the .env
file is loaded AFTER the ORIGIN
value is requested by SvelteKit. This happens because you import the import { handler } from "./build/handler.js";
before running the dotenv.config();
.
Unfortunately, this module tries to resolve the ORIGIN immediately during import so there isn't much we can do here.... but, before you jump into changing the order, keep reading.
The second issue you have is that NodeJS runs the import statements first so, even if you swap the lines so that the .env
file is loaded before the import, it still would not work.
So, what solution can we apply here?
There are 2 options we can take: either inject the variable into the process without an .env
file and then run the code or import the .env
file and then run the code.
In order to inject the variable before running the code you need to run your code like this:
ORIGIN=http://localhost:3000 node server.js
This time, this line is a command you need to run. If you run this line, you don't need the .env
file (although it is not harmful and you can leave it if you have other variables).
Instead, if you want to import the .env
file completely, you need to run the command like this instead:
NODE_OPTIONS='-r dotenv/config' node server.js
At least you can update your package.json
to include those changes in the start
script so that you can continue using npm run start
as an alias.