Nodejs set Cookies not being sent to firebase frontend react app - node.js

I'm trying to set cookies on the frontend firebase from nodejs app on a different server.
I have allowed whitelisted the frontend URL from cors.
Also, set the headers.
appRouter.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin','*');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);
res.cookie('cokkieName',138932843821341, { maxAge: 900000, httpOnly: false, sameSite: 'none', secure: true })
// Pass to next layer of middleware
next();
}
)
appRouter.use(cors(
{
credentials: true,
origin: [
'http://localhost:3000',
'https://mywebsitename.com',
'https://localhost:3000'
]
}));
// parse application/x-www-form-urlencoded
appRouter.use(bodyParser.urlencoded({ extended: false }))
appRouter.use(cookieParser("secret"));
appRouter.use(session({
cookie:{
httpOnly:false,
maxAge: 1*60*60*1000},
resave: false,
saveUninitialized: true,
secret: 'secret' ,
sameSite:false,
secure: true
}));
Through postman or even through running the backend(which is on a different server) URL, I do get the cookies. But on the firebase frontend, I don't get the cookies.
There was a cors error but I resolved it by adding the frontend URL to the origin whitelist.
The backend is communicating with the frontend. I say this because the backend response is logged on the browser and the data is visible. However, the cookies are not.
I also have google authentication which, after successfully closing the window of account selection, sets the various google auth cookies to the frontend.

Related

Cookie not send with fetch in react even though the cookie is set in the browser Firefox or Brave

I am learning and applying authentication with google Oauth2.0, and i am using with passport including express-session to handle login session, however, i am having trouble with Firefox and Brave after deploying, the cookie is not send with the fetch call, i check in the devtool the cookie is set successfully with Oauth callback, but i notice in the request header from my fetch call the cookie is indeed absent. My code settings are as follows:
App js :
//require setting
const app = express();
app.use(helmet());
app.use(express.json());
app.use(cors({
origin: process.env.FRONTEND_URL,
methods: "GET, POST, PUT, DELETE",
credentials: true
}));
app.set('trust proxy', 1)
app.use(session({
secret: process.env.COOKIE_SECRET,
resave: false,
saveUninitialized: false,
cookie: {
secure: "auto",
maxAge: 1000 * 60 * 60 * 2,
sameSite: "none", //false in developement
},
store: pgStore, // this is working
}));
app.use(passport.initialize());
app.use(passport.session());
app.use("/v1", api);
My fetch request from the client side which I use to check if the user is authentificated, I will get the userdata, otherwise i do nothing
async function httpGetUser() {
return await fetch(`${REACT_APP_BASE_URL}/auth/login`, {
credentials: "include",
headers: {
'Content-Type': 'application/json',
'Access-Control-Allow-Credentials': true,
}
})
};
Well in Chrome browser looks like it work fine, but if it doesn't work with firefox and brave that mean i must do something wrong and i wasn't able to figure out despite some research on the documentation.
UPDATE2: after fighting with cookie for 3 days: Chrome and Edge work without issue, for some unknown reason even thought the cookie is set on the browser after the callback response header, they're not blocked since i can see them on Brave and Firefox, but i just can't fetch with the credentials on the request header despite checking the sameSite attribut in express-session, cors..
UPDATE3: I manage to make it work with Firefox but it's random, if i clear out the cookie it could stop working but sometimes it rework miraculously.. as for Brave still impossible.

Express CORS request with axios fails

I have an authentication cookie that I want to send to an express server. The request is supposed to send both JWT from the localStorage(which it does) and a cookie that is previously set.
The cookie is set by the following response from an endpoint:
res
.cookie("cookiename", "cookievalue", {
maxAge: 86400 * 1000,
httpOnly: false,
secure: false,
})
.sendStatus(200);
The cookie appears correcly in the DevTools:
Then, I want to use the cookie in every subsequent request:
First I set withCredentials globally to true:
axios.defaults.withCredentials = true;
Then I make a request with intentions of sending the cookie:
axios
.get("http://localhost:5000/userLikedPlaces", {
headers: {
jwt: localStorage.getItem("jwt"),
"X-Requested-With": "XMLHttpRequest",
"Content-Type": "application/json",
"Access-Control-Allow-Credentials": true,
},
params: { limit: likedQueryOffset },
})
However, I get an error:
By what I understand, I should set Access-Control-Allow-Origin to my localhost:3000 address, so I copy the following code:
server.use(function (req, res, next) {
// Website you wish to allow to connect
res.setHeader("Access-Control-Allow-Origin", "http://localhost:3000");
// Request methods you wish to allow
res.setHeader(
"Access-Control-Allow-Methods",
"GET, POST, OPTIONS, PUT, PATCH, DELETE"
);
// Request headers you wish to allow
res.setHeader(
"Access-Control-Allow-Headers",
"X-Requested-With,content-type"
);
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader("Access-Control-Allow-Credentials", true);
// Pass to next layer of middleware
next();
});
The other middlewares are:
server.use(cors());
server.use(cookieParser("MySecret"));
server.use(bodyParser.urlencoded({ extended: false }));
server.use(bodyParser.json({ limit: "10kb" }));
server.use(cors({ credentials: true, origin: "http://localhost:3000" }));
I am rather bewildered, since I have looked at a considerable number of similar questions, and this header seems to fix the issue, but apparently not here.
My question is how to fix the CORS issue, getting the cookie from localhost:3000(client) to localhost:5000(server)?
The problem was the fact that the default configuration of the CORS middleware uses the wildcard attribute, and is the reason why all request were blocked. Solution is to use the custom configuration:
server.use(cors({ credentials: true, origin: "http://localhost:3000" }));

Unsure as to why no cookie is being sent back to my localhost client when using express-session

Having issues with node express-session and basically just trying to understand how it all works with regards to cookies and my session store within my postgres database.
For starters, I'm not sure why I don't receive a session id cookie within my chrome browser where my react app is running on localhost:3000. If I call the route localhost:5000/login from postman, a cookie is received but when calling the same route from Chrome: localhost:5000/login and then check my cookies, nothing is created when using the fetch API.
The session is created fine within postgres.
Here is my middleware for session setup:
app.use(session({
store: new pgSession({
pool : pool, // Connection pool
schemaName: 'my_schema',
tableName : 'user_sessions'
}),
secret: randomString.generate({
length: 14,
charset: 'alphanumeric'
}),
resave: false,
saveUninitialized: false,
cookie: { maxAge: 1000 * 60 * 60 * 24,
httpOnly: true }
}))
app.use(function (req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
res.header('Access-Control-Allow-Methods', 'PUT, POST, GET, DELETE, OPTIONS');
next();
});
My other question is, within my react app, how can I use the session info within my postgres db to check that all requests to all routes are still coming from the same user on the client side?
try this , change your cors middleware this
app.use(cors({ origin: true, credentials: true }));
and add this when you make your request
withCredentials: true,
credentials: "include",
I had same problem I was recieving the cooking when making post from postman, but not from the browser when making request with axios, hopefully it works for you too as well

Having troubles sharing sessions between subdomains in express

I'm trying to share a session between multiple subdomains (under the same root domain), so user can login in dashboard.example.com, and when viewing x.example.com, he will be identified on backend.
I'm using express with express-session and passport.js and my backend server is sitting behind NGINX server. I went through all topics I could find here, but none of them helped me fix the issue.
Here is my express-session configuration:
{
store: redisStore,
secret: 'secret',
name: 'app.sid',
resave: false,
saveUninitialized: true,
proxy: true,
cookie: {
secure: true,
expires: Date.now() + parseInt(process.env.COOKIE_EXPIRATION_MS, 10),
maxAge: parseInt(process.env.COOKIE_EXPIRATION_MS, 10),
httpOnly: true,
domain: '.example.com'
}
}
I read on some threads here I should set response headers as well:
app.use((req, res, next) => {
res.header('Access-Control-Allow-Credentials', true)
res.header('Access-Control-Allow-Origin', '*')
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE')
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept')
next()
})
When logging into the app through dashboard.example.com, the session is created fine, and on browser I see the cookie session as expected (app.sid=123)
When going to x.example.com, the same session is being sent to the server (app.sid=123), but the session is not extracted from the redis store. Instead, it overrides '123' key in redis with an empty state, and now the state is also gone for dashboard.example.com
Any help / directions would be appreciated!
Thanks!

Express session is empty in Safari

I'm building a Node.js application with express. I use express-session for sessions. The data I store in a session is available in IE, Chrome and Firefox. But in Safari the session is empty all the time. So when I do console.log(req.session) it prints:
Session {
cookie: {
path: '/',
_expires: null,
originalMaxAge: null,
httpOnly: true,
secure: true
},
userHasCheckCorrect: true
}
This are my settings in server.js
app.use(session({
secret: process.env.SESSION_SECRET,
resave: false,
saveUninitialized: true,
cookie: {
secure: true,
httpOnly: true
}
}));
It's a server with SSL certificate so it's a HTTPS domain. With HTTP it seems to work fine in Safari. What am I doing wrong here? Is there a setting I'm missing? I've looked on many places but couldn't find the answer yet. And why does it work in all browsers expect for Safari?
With Safari it is required to pass in credentials: 'include' in request header, otherwise it doesn't send cookies.
You might also want to set a global response header after your set your session middleware by something like this:
app.use(function(req, res, next) {
res.set('credentials', 'include');
res.set('Access-Control-Allow-Credentials', true);
res.set('Access-Control-Allow-Origin', req.headers.origin);
res.set('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.set('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
next();
});

Resources