R
Railway13mo ago
.

NGINX Reverse proxy

Description: -Frontend URL: https://frontend.com -Frontend is a React App hosted on railway -Backend URL: https://backend.com -Backend is being hosted locally since I need my GPU for ML model. -Backend is ngrok http tunnel (static domain) => localhost:80 (dockerized nginx on my PC) then reverse proxy into another docker container, which is on the same docker-network and is running nodejs server. -Nodejs server uses express-session, and passport with google-oauth-strategy20. A normal request from frontend to backend looks like: https://frontend -> https://backend (ngrok url) -> http://localhost:80 (nginx on local computer) -> http://backend-container:8800 (nodejs server in same docker network as nginx) Problem: The app works fine when I use cross-site requests from my frontend to my backend. Ex: -I am redirected to google login using this route
<a href=https://backend/login/google> ... </a>
<a href=https://backend/login/google> ... </a>
After logging in, redirected back to frontend with a cross site cookie from backend. I am then able to authenticate normally with my server. -check for a user
fetch(https://backend/exists, {method:post, credentials:true})
fetch(https://backend/exists, {method:post, credentials:true})
The issue is that on browsers that block third party cookies, the authentication system breaks (ex: Safari mobile). How can I rearrange my project so my requests are no longer cross-origin? I've tried to create a nginx proxy in the same container as my frontend, and route /api to the backend. Ex:

listen 80;

location /api {
proxy_set_header Host $host;
proxy_pass http://backend;
proxy_set_header Cookie $http_cookie;
}

location / {
proxy_set_header Host $host;
proxy_pass http://localhost:3000 #React frontend;
}

listen 80;

location /api {
proxy_set_header Host $host;
proxy_pass http://backend;
proxy_set_header Cookie $http_cookie;
}

location / {
proxy_set_header Host $host;
proxy_pass http://localhost:3000 #React frontend;
}
Then from frontend, send requests like:
fetch(/api/exists, {credentials: true, method: post})
fetch(/api/exists, {credentials: true, method: post})
<a href="/api/login/google">...</a>
<a href="/api/login/google">...</a>
I'm not sure If conceptually what I'm doing makes any sense, but "/api" routes dont work. Please help!
6 Replies
Percy
Percy13mo ago
Project ID: N/A
.
.OP13mo ago
N/A
Brody
Brody13mo ago
its not nginx, but its a ready made solution https://railway.app/template/7uDSyj
pandas
pandas13mo ago
if you are talking about "The issue is that on browsers that block third party cookies, the authentication system breaks (ex: Safari mobile)." very well known issue and third party cookies https://developer.chrome.com/en/docs/privacy-sandbox/third-party-cookie-phase-out/ that tells you everything, why not store cookie on a frontend? another thing https://github.com/JakeChampion/fetch#sending-cookies "For CORS requests, use credentials: 'include' to allow sending credentials to other domains" don't forget to add Access-Control-Allow-Credentials to the server as well thats neat thanks for sharing
.
.OP13mo ago
@Brody @pandas A little late but thank you! This is pretty much exactly what I needed. In case anyone is having the same issues, it took some restructuring of my backend. The solution was to separate authentication into its own server, which resides on the same internal network as the frontend and Caddy server. All /api requests go through the authentication server, which can now issue a same-site cookie, then reroute traffic to my ngrok http tunnel.
Brody
Brody13mo ago
awesome, an auth server sounds like a perfect solution
Want results from more Discord servers?
Add your server