I’m new to Nginx and ubuntu – have been with windows server for over a decade and this is my first try to use ubuntu and Nginx so feel free to correct any wrong assumption I write here 🙂
my setup: I have an expressjs app (node app) running as an upstream server. I have front app – built in svelte- access the expressjs/node app through Nginx proxy_reverse. Both ends are using letsencrypt and cors are set as you will see shortly.
When I run front and back apps on localhost, I’m able to login, set two cookies to the browser and all endpoints perform as expected.
When I deployed the apps I ran into weird issue. The cookies are lost once I refresh the login page. Added few flags to my server block but no go.
I’m sure there is a way – I usually find a way – but this issue really beyond my limited knowledge about Nginx and proxy_reverse setup. I’m sure it is easy for some of you but not me. I hope one of you with enough knowledge point me in the right direction or have explanation to how to fix it.
Here is the issue:
my front is available at travelmoodonline.com. Click on login. Username : mongo@mongo.com and password is 123.
inspect dev tools network. Header and response are all set correctly. Check the cookies tab under network once you login and you will get two cookies, one accesstoken and one refreshtoken.
Refresh the page. Poof. Tokens are gone. I no longer know anything about the user. stateless.
In localhost, I refresh and the cookies still there once I set them. In Nginx as proxy, I’m not sure what happens.
So my question is : How to fix it so cookies are set and sent with every req? Why the cookies disappear? Is it still there in memory somewhere? Is the path wrong? Or the cockies are deleted once I leave the page so if I redirect the user after login to another page, the cookies are not showing in dev tools.
My code :
node/expressjs server route code to login user:
app.post('/login', (req, res)=>{
//get form data and create cookies
res.cookie("accesstoken", accessToken, { sameSite: 'none', secure : true });
res.cookie("refreshtoken", refreshtoken, { sameSite: 'none', secure : true }).json({
"loginStatus": true, "loginMessage": "vavoom : doc._id })
}
Frontend – svelte – fetch route with a form to collect username and password and submit it to server:
function loginform(event){
username = event.target.username.value;
passwordvalue = event.target.password.value;
console.log("event username: ", username);
console.log("event password : ", passwordvalue);
async function asyncit (){
let response = await fetch('https://www.foodmoodonline.com/login',{
method: 'POST',
origin : 'https://www.travelmoodonline.com',
credentials : 'include',
headers: {
'Accept': 'application/json',
'Content-type' : 'application/json'
},
body: JSON.stringify({
//username and password
})
}) //fetch
Now my Nginx server blocks :
# Default server configuration
#
server {
listen 80 default_server;
listen (::):80 default_server;
root /var/www/defaultdir;
index index.html index.htm index.nginx-debian.html;
server_name _;
location / {
try_files $uri $uri/ /index.html;
}
}
# port 80 with www
server {
listen 80;
listen (::):80;
server_name www.travelmoodonline.com;
root /var/www/travelmoodonline.com;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
return 308 https://www.travelmoodonline.com$request_uri;
}
# port 80 without wwww
server {
listen 80;
listen (::):80;
server_name travelmoodonline.com;
root /var/www/travelmoodonline.com;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
return 308 https://www.travelmoodonline.com$request_uri;
}
# HTTPS server (with www) port 443 with www
server {
listen 443 ssl;
listen (::):443 ssl;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
server_name www.travelmoodonline.com;
root /var/www/travelmoodonline.com;
index index.html;
ssl_certificate /etc/letsencrypt/live/travelmoodonline.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/travelmoodonline.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
location / {
try_files $uri $uri/ /index.html;
}
}
# HTTPS server (without www)
server {
listen 443 ssl;
listen (::):443 ssl;
add_header Strict-Transport-Security "max-age=63072000; includeSubDomains; preload";
server_name travelmoodonline.com;
root /var/www/travelmoodonline.com;
index index.html;
location / {
try_files $uri $uri/ /index.html;
}
ssl_certificate /etc/letsencrypt/live/travelmoodonline.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/travelmoodonline.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
server_name foodmoodonline.com www.foodmoodonline.com;
# localhost settings
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_cache_bypass $http_upgrade;
# proxy_cookie_path / "/; secure; HttpOnly; SameSite=strict";
# proxy_pass_header localhost;
# proxy_pass_header Set-Cookie;
# proxy_cookie_domain localhost $host;
# proxy_cookie_path /;
}
listen (::):443 ssl; # managed by Certbot
listen 443 ssl; # managed by Certbot
ssl_certificate /etc/letsencrypt/live/foodmoodonline.com/fullchain.pem; # managed by Certbot
ssl_certificate_key /etc/letsencrypt/live/foodmoodonline.com/privkey.pem; # managed by Certbot
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
}
server {
if ($host = www.foodmoodonline.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
if ($host = foodmoodonline.com) {
return 301 https://$host$request_uri;
} # managed by Certbot
listen 80;
listen (::):80;
server_name foodmoodonline.com www.foodmoodonline.com;
return 404; # managed by Certbot
}
I tried 301-302-307 and 308 after reading about some of them covers the GET and not POST but didn’t change the behavior I described above. Why the cookie doesn’t set/stay in the browser once it shows in the dev tools. Should I use rewrite instead of redirect???? I’m lost.
Not sure is it nginx proxy_reverse settings I’m not aware of or is it server block settings or the ssl redirect causing the browser to loose the cookies but once you set the cookie, the browser suppose to send it with each req. What is going on here?
Thank you for reading.