I have a frontend that talks to a backend.
When logging in, the backend creates a cookie and returns it to the client.
When logging out, i want the backend to delete the cookie.
As you can see, i did not set any of the attributes below.
This is the request that is sent from the front.
const response = await axios.get(
`${backendAddress}/api/v1/auth/logout`,
{
withCredentials: true,
credentials: "include",
}
);
This is what I do in the backend
res.setHeader('Set-Cookie', `user-data=; Max-Age=0; path=/; domain=${BACKEND_DOMAIN}`);
res.end();
and these are the cors configuration:
app.use(cors({ origin: CLIENT_URL, credentials: true }));
Locally, this works, I see the Set-Cookie header in the response and I can see that the browser deletes the cookie.
On azure, I run the backend as a web app in azure, and the frontend as a static web app, and connect both of them using the api feature of the static web app.
When i check what headers i receive on the same request that work locally, I can see that the Set-Cookie header is missing.
When looking at the request that is sent to the webapp (the backend), I do see that the cookies are sent with it. And that the cors headers in the response include the right origin and credential headers. I also made sure that the versions of both front and backend are up to date.
Any idea what might cause the Set-Cookie to "disappear" on its way to the browser?
Thanks!
Related
I've built an Node.js Express API where whenever the user uses the (POST) /login, if logged successfully, the api will set the Authorization Token such as this:
#Post('/login')
#UseBefore(validationMiddleware(LoginUserDto, 'body'))
async logIn(#Res() res: Response, #Body() userData: LoginUserDto) {
const { cookie, user } = await this.authService.login(userData);
res.setHeader('Set-Cookie', [cookie]);
return user
}
Whenever I run the docker image locally, if it was requested by a React app it would create the token as a cookie in the browser successfully.
Since it was working, I deployed in docker image of the API in Azure and Digitalocean (in order to see if would work on both. But when I tried to login with the deployed API, it would POST with success but the cookie wouldn't be set in the browser when using the React App (in the app the credentials were set to true in order to save).
I tried to call the deployed API with Postman and Insomnia and both would save the cookie from the successful login.
With this last experiment I was really confused because the API works as expected both in postman and in the react app when run locally, but when deployed only works as expected in postman and not in React. I can't understand if the problem is from react or from the API.
I have also tried using RTK and Axios in react and both got the same results.
In the CORS options from the API the origin is set to "*"
Already found out, seems like when creating the cookie I was not setting the Same-Site property and by default was Lax, which didn't let the browser save the cookie. I set it to none and needed to put secure after it.
public createCookie(tokenData: TokenData): string {
return `Authorization=${tokenData.token}; HttpOnly; Max-Age=${tokenData.expiresIn}; SameSite=None; Secure`;
}
Actually I create a project on reactjs have two service. First is client service that is running on localhost port 3000 and second is server service that is running on port 8000. I created cookie on server service and wants to access from client service. But the cookie save on the sever port. How to save this cookie on client service or access the cookie from client service.
This is the code on the sever service
res.cookie("jwt",token,{expires:new Date(Date.now()+99999,
httpOnly: true
})
I fixed it by using the withCredentials property.
Axios Request from a different domain cannot set cookie values for their own domain unless withCredentials is set to true before making the request.
axios.get('some api url', {withCredentials: true});
I also included origin as true and credentials as true in cors
const corsOptions = {
origin: true, //included origin as true
credentials: true, //included credentials as true
};
app.use(cors(corsOptions));
Now it works fine for me. It send a response cookie to the client server.
see here
I'm building a Next.js app using Strapi as a CMS and authentication server. I've managed to get a JWT from the auth endpoint, and have stored it in a cookie. To retrieve secured content from strapi I need to send this JWT in the header
I'm using Apollo to send graphQL queries to strapi, according to their documentation, I can easily set auth headers by adding this to utils/apollo.js
const authLink = setContext((_, { headers }) => {
// get the authentication token from local storage if it exists
const token = cookies.get('jwt') <-- This is what I'd like to do, but I can't figure out how to access cookies at this point.
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
How can I access cookies in the app mentioned above. It's not part of a component, though it is used to build a HOC?
While using localstorage is an option, I've read that cookies are a safer way to store data.
Using cookies with secure isn't an option - I'm not sure if strapi allows it, and also because there are multiple frontend origins vercel builds previews for all branches
Once you set the cookie it will be passed in the Cookie header so you need to retrieve it from there, not the cookies object which is only available in the browser but not available in server-side requests. In addition, if you're using CORS you will need to enable credentials both in the client and server, specifically in the client you need to set credentials: 'include'. This is required setting for cookies to work.
I am a little bit confused about how HTTP works.
My question is that when the server assigns a JWT token to a client after providing credentials, the server assigns token in HTTP header['Authorization']. Now the user is logged in and can make a request.
So please tell me if when the user makes an API call again, will the HTTP header['Authorization'] remain same or be changed?
The header['Authorization'] remains the same.
The server basically generates a token and sends it to the client-side.
On the client-side, the token will be saved in the request header of subsequent requests sent to the server.
Please check this resource
Yes client has to do every request with authorisation request (protected routes )
so you have to set up a axios configuration (https://github.com/axios/axios#axioscreateconfig)
const instance = axios.create({
baseURL: 'https://some-domain.com/api/',
timeout: 1000,
headers: {'X-Custom-Header': 'TOKEN'}
});
And you have to know how this authentication and authorisation tokens works for this please go through this (https://blog.restcase.com/4-most-used-rest-api-authentication-methods/)
I'm trying for days now to send a valid redirect request in my App.
What should happen:
If I try to perform an action that requires me to be logged in, my express app should redirect to the login URL.
router.use(function(req,res,next){
if(req.session.user == null){
res.redirect('http://localhost:4200/#/login');
}
else
next();
});
My CORS implementation:
var corsOptions = {
origin: process.env.ctxCliente,
credentials: true
}
app.use(cors(corsOptions));
The error:
XMLHttpRequest cannot load http://localhost:4200/#/login. Response to
preflight request doesn't pass access control check: The value of the
'Access-Control-Allow-Origin' header in the response must not be the
wildcard '*' when the request's credentials mode is 'include'. Origin
'null' is therefore not allowed access. The credentials mode of
requests initiated by the XMLHttpRequest is controlled by the
withCredentials attribute.
On my Angular App I'm sending {withCredentials: true} with all requests, because I need to use a cookie to verify the user session id
After a lot of trial and error I solved the problem:
Angular should intercept https request and check for redirects.
Here is how an interceptor can be implemented:
https://angular.io/guide/http#intercepting-all-requests-or-responses