express
express copied to clipboard
Cookies set on development, but not on production
2 Docker containers:
- Server: Express.JS REST API with JWT authentication.
- Client: Next.JS app that uses Axios to talk with the server.
I tested it on localhost with Docker Compose: Everything working fine (both Postman and the browser successfully store the token as a cookie to use on subsequent requests.).
I deployed it to Google Cloud Run (one service for each container). Everything working fine except that now only requests made through Postman are storing the token as a cookie.
The browser (the Next.JS app) no longer does the same, even though the request returns a successful response there is no token in the browser cookies.
I did some research, found a few similar problems, and the solutions usually involve setting up some CORS configurations, so I updated my code by adding these configurations, but the issue remains.
I am currently trying it like this:
Server-side:
export const login = async (req: Request, res: Response) => {
...
const accessToken = jwt.sign({ username, id, isAdmin }, jwtSecret, {
expiresIn: "12h",
});
res
.status(200)
.cookie("accessToken-Myapp", accessToken, {
secure: true,
sameSite: "none",
})
.end();
};
const app = express();
app.use(helmet());
app.use(
rateLimit({
max: 300,
windowMs: 60 * 60 * 1000,
message: "Please try again later!",
})
);
const corsConfig = {
origin: true,
credentials: true,
allowedHeaders: ["Content-Type", "Authorization"],
};
app.use(cors(corsConfig));
app.options("*", cors(corsConfig));
app.use(express.json());
app.use(cookieParser());
app.use("/images", express.static("images"));
app.get("/health", (_, res: Response) => res.sendStatus(200));
app.use("/api/v1/auth", authRouter);
Client-side:
import axios from "axios";
export default axios.create({
baseURL: `https://my-cloud-run-server-container-address/api/v1/`,
withCredentials: true,
});
Are you running the NextJS app locally, and backend elsewhere? If that is so, your cookie probably got restricted to the backend's ip/domain
in your login function, try setting httpOnly to true, your cookie might be deemed insecure as clientside JS can access it, and might be ignored
res .status(200) .cookie("accessToken-Myapp", accessToken, { secure: true, sameSite: "none", httpOnly: true }) .end(); };
I agree with @danillo7789, here's the same thing,
res
.status(200)
.cookie("accessToken-Myapp", accessToken, {
secure: true, // Ensure you are using HTTPS in production
httpOnly: true, // This ensures the cookie is not accessible via JavaScript
sameSite: "none"
})
.end();
Also, I would take a look at this res.cookie(name, value [, options]) in Express 4x API Reference.