Vue-cookies with Firebase and Heroku, not being sent - node.js

I have a Vue.js project deployed on firebase and a node-express app deployed on Heroku. Now I want to send cookies along with each request to the server using Axios. I am using Axios and cookies are being set using vue-cookies (which are of sameSite: none and secure: true attributes).
In localhost, I can see the cookies in each request in my backend and can access them using req.cookies.session. (The session is my cookie name that is saved on the client-side.)
But in production, I can't see the cookies in the request. What am I doing wrong?
node-express cors
app.use(cors({
credentials: true,
origin: 'https://paid-kickstartu-webapp.web.app',
'Access-Control-Allow-Origin': '*',
}));
Also attaching my screenshots of both Axios configuration and node-express backend for more understanding. Everything is working but cookies are not being sent in the backend from the frontend. In localhost both work as required.

Try this
If you are using Firebase Hosting + Cloud Functions, __session is the only cookie you can store, by design. This is necessary for us to be able to efficiently cache content on the CDN -- we strip all cookies from the request other than __session. This should be documented but doesn't appear to be (oops!). We'll update documentation to reflect this limitation.
Also, you need to set Cache-Control Header as private
res.setHeader('Cache-Control', 'private');

Thank you all for helping. I have solved this problem, what I was doing before was getting the cookie in res body and saving the cookie on the client-side using vue-cookie, So any call to the backend was showing me empty cookies. But now I am setting the cookie header from my backend (node-express) during login and now when I send any further request's I can see the previous cookies that were set in my headers during login.

Related

Response header Set-Cookie doesn't store cookies in browser

I'm setting 2 cookies in response from backend to the browser.
One that is secure HTTPOnly (it's refreshToken) and the other one without those parameters so it's accessible to JavaScript (carrying information about refreshToken is set and when it expires).
Cookies in response:
Neither of those two is set in browser. I studied all about cookies and I'll be honest, I'm lost here and need your help.
At first it was working very well on my localhost environment (backend on localhost:8080, frontend on localhost:3000).
Then I made deploy and there it was NOT working.
I tested again on localhost and I checked "Disable cache" to prevent unwanted behaviour and it is not working even there.
I'll mention that I'm using CORS, not sure if that can may interfere:
I tested this both in Chrome and Firefox.
I FINALY figured it out. Cookies are valid. The answer is to set withCredentials = true both in frontend and backend.
First I thought the parameter withCredentials on frontend is used only when we want to send our credentials hidden in secure HttpOnly cookies to which we don't have access to but browser does.
Apparently it is also used when we want to set cookies from response. Link to docs.
responses from a different domain cannot set cookie values for their own domain unless withCredentials is set to true before making the request
Secondly, we also have to add withCredentials on backend to CorsFilter (in Spring boot) otherwise we get CORS error.
CorsConfiguration()
.apply {
allowedOrigins = listOf(uiUrl)
allowedHeaders = listOf("*")
allowedMethods = listOf("*")
allowCredentials = true
}

Not able to receive/set cookies in browser from backend in MERN app with backend hosted on heroku and frontend on netlify

I have a MERN app whose backend is hosted on Heroku and frontend on netlify. I am not able to see the cookies in the browser after deploying the app but it works fine on localhost. I think it is due to different backend and frontend ports, what am I missing, please help
You are correct. Cookies are not cross-domain compatible. If it was, it would be a serious security issue. The easiest way to fix your problem would be to send back the cookie as a res object, and then setting the cookie manually in the frontend.
Take this for example. I'll do this with JavaScript style pseudocode. Don't copy paste this as this most likely wouldn't work right away. This is what you're going to do on the back-end:
// 1. Authenticate the user.
const userData = await authenticateUser();
const userToken = await verifyUser(userData);
// 2. Return the response object.
return response.status(200).json({
status: 'success',
data: userData,
token: userToken,
});
In the front-end:
const response = await axios.post(...); // your API call, will return above object.
// set your authentication token here.
// the 'options' object will contain all possible cookie options, example would be 'secure'.
cookies.set('token', response.data.token, options);
// alternatively, set the cookie in the local storage.
localStorage.setItem('token', response.data.token);
You need to set the cookie accordingly in the front-end.
Further reading: MDN Docs
EDIT: Your question is unclear. First time you talked about cookies, but now you're talking about httpOnly cookies. Please be more specific in your questions.
It is impossible to set httpOnly cookies in React.js if it is cross-domain. React is only responsible for the 'view' of the website. httpOnly cookies are only meant to be set server-side. Client-side JavaScript cannot read or set that specific cookie, but it is able to send it. Unless you have something in your Netlify that can do server-side operations, I don't think that is possible.
Your best bet is to actually just use the same domain.

Cookies not set when nodejs server is not on localhost

I have a ReactJS frontend and a NodeJS backend. The frontend calls the login API from NodeJS it returns a cookie with the JWT token which will be used for other calls. I've tested it and it works when both the frontend and backend are running on localhost.
I've used postman and called the same API. One running on localhost and one running on AWS EC2. Both returns the same response, however, the one running on EC2 doesn't set the cookie. set-cookie header is present on both.
I've included the cors configuration.
var corsOptions = {
origin: ['http://localhost:3001'],
credentials: true
}
app.use(cors(corsOptions));
FOUND THE PROBLEM:
Turns out safari was blocking the cookies. Chrome on iOS is affected by it too. Turning off the option "Prevent cross-site tracking" on safari preferences solved the issue
try to use the full link to send a request to API
axios.post('https://mysite/api/v1/login', {email,password,...})

Unable to get session cookie using axios and Express Session. But able to with Postman

I have been able to find countless topics of discussion on this, but none of the solutions seem to work for me
Essentially, I have a react client that uses axios to make requests to a node js backend which uses express session
I’m able to log into the application and get a successful response. However, the response header does not include the connect.sid field. And when checking chromes devtools -> application -> cookies folder, I don’t see any cookies there for the site
I also tried testing this using IE and Firefox with the same result
Now when making the same login request via postman, I’m able to see both the connect.sid in the header and the cookie itself in the cookies tab.
In my current situation, the client and server are both running on localhost, with the client running on port 3000 and the server running on port 3001. One difference is that client is http and server is https
From my research online, these are the common things suggested, with neither working in my case
Setting axios withCredential to “true” in react. This appears to have fixed the problem for majority of the people online. I have mine set up as well
import axios from "axios";
axios.defaults.withCredentials = true;
Setting the httpOnly field to false for the session cookie in the server. Below is my session configuration
app.use(session({
secret: 'BSL3562904BVAIHBP53VRFSF',
resave: false,
saveUninitialized: false,
rolling: true,
cookie: {secure: true, httpOnly: false }
}))
Configuring the cors settings in the server. This shouldn’t affect me in this scenario as the client and server are running on the same domain, but I still covered that base anyway
app.use(cors({
credentials: true,
origin: "http://localhost:3000"
}));
For the origin value I tried both “localhost” and “127.0.0.1”
Setting “trust proxy” in server
app.set('trust proxy', 1);// trust first proxy
This isn’t simply an issue of not being able to retrieve cookies in the client, as I can create and attach cookies to the response and see them. It’s just the session cookie that does not appear
At this point, I’m kind of banging my head against a wall. So any help or suggestions would be much appreciated!

Specific Endpoint: Access Denied (no Access-Control-Allow-Origin header) on API Request in React/Redux App with Node

I cannot access a custom heroku API endpoint in a react/redux app. The heroku endpoint loads up fine in a browser, and I can see the network request coming back on my console, so it seems something in my app itself is preventing it from returning.
It's the classic 'No 'Access-Control-Allow-Origin' header is present on the requested resource' error, but what's perplexing is that I can use another endpoint (such as openweather's API) and don't get this error.
Do I need to use Express or other middleware to deal with Heroku specifically? I'm creating a store with ReduxPromise middleware right now and am using Axios to make the request. Or is there a server side configuration on Heroku that might change this?
Thanks for your help, pretty new to react/redux/node =)
This is a CORS issue, you need to add a cors configuration into your API request and accept the origins on the server side using access-control-allow-origin header and accepting the referrer url of the request.
These are my configuration options when using redux-api to make the requests, look at the documentation for your specific framework:
export const baseOptions = {
mode: 'cors',
credentials: 'include',
headers
}

Resources