Why am i getting a authorization header when i send the requests to / from the client but when i send requests to /auth/signup on the same origin i'm not getting the authorization headers.
Here is how i'm setting my cookie in the browser so that i will send them as a header from the browser.
export const storeRefreshToken = (res: Response, token: string): void => {
// Invalidate old tokens
res.cookie(__cookieName__, token, {
httpOnly: true, // they can not be accessed using javascript
path: "/",
sameSite: "lax",
});
};
I'm using jwt authentication and graphql, I'm getting the headers when i'm at / but if i change to /auth/signin I'm not getting anything. What may be posibly the problem when setting cookies.
Related
in my express i use res.cookie to post a cookie
res.cookie("jwt", token, {
expires: new Date(Date.now() + process.env.COOKIEEX * 24 * 60 * 60 * 1000),
withCredentials: true,
httpOnly: false,
});
res.status(200).json({
status: "success",
user,
token,
});
but when i send a req to that middleware from my react app using axios i find the cookie in the network > headers> set-cookie , but its not sets in the browser:
<form
onSubmit={async (e) => {
e.preventDefault();
const res = await axios.post(
"http://127.0.0.1:3000/api/v1/users/login",
{
email: "na#test.test",
password: "password#",
},
{ credentials: true }
);
}}
>
i also tried to set samesit=None and secure, its works and i can see the cookie in the browser but after refreshing the page it disappears :
res.cookie("jwt", token, {
expires: new Date(Date.now() + process.env.COOKIEEX * 24 * 60 * 60 * 1000),
withCredentials: true,
httpOnly: false,
sameSite:"None",
secure:true
});
Browsers are less and less likely to include cookies over HTTP, instead you should try to only use HTTPS when a browser is involved.
Samesite=none;secure only works over HTTPS and will not be included in requests over HTTP. When you don't include any samesite, the default is then set to Lax (I think) and that means that it will not be included in POST requests to a different site. To do cross-site requests with cookies, you need to set samesite=none;secure and use HTTPS.
As far as I know, when you work with cookies, the backend (express in your case) handle the settings of the cookies in your browser [SESSION], in an another word, you just need to set { credentials: true } in your frontend app, the token that was saved on your browser is logically saved in your DB, so whenever a request coming, there is a check on the DB if the two tokens matches [ the one coming from the req and the one is saved on your DB ].
So mainly, or again as I know it's not gettable in other word if you just need something which is included in your token, just send it explicitly.
I am unable to retrieve a cookie that I sent earlier.
As part of login, I sent back a refresh token as an httpOnly cookie.
const payload = {name, email};
console.log("payload: ", payload);
const accessToken = jsonwebtoken.sign(payload, process.env.ACCESS_TOKEN_KEY, { expiresIn: '15m' });
const refreshToken = jsonwebtoken.sign(payload, process.env.REFRESH_TOKEN_KEY, { expiresIn: '1d' });
console.log("Access Token:", accessToken); // access token is generated
console.log("Refresh Token:", refreshToken); // refresh token is generated
res.cookie('refreshToken', refreshToken, { httpOnly: true, secure: false, sameSite: 'Lax', maxAge: 24*60*60*1000 }); // call succeeded. what is the name of cookie?
res.json({ accessToken });
Later on a refresh endpoint I look for a cookie and can't find it:
export const handleRefreshToken = async (req, res) => {
console.log("Request Cookies", req.cookies);
const cookies = req.cookies;
if (!cookies?.refreshToken) return res.sendStatus(401);
I see the following cookies:
_ga: 'xxxxxxxxxxxxxxxxx',
_gid: 'xxxxxxxxxxxxxxxx',
_gat_gtag_UA_xxxxxx: 'x',
_ga_QPY49S2WC4: 'xxxxxxxxxxxxxxxxxxx'
This is on my dev environment with nodejs running on localhost:5000.
Update: Using devtools (Network) I see the cookie in the response on the client side. The name of the cookie is 'refreshToken'. However, the cookie doesn't show up on the browser when I look at the cookies on the browser. Perhaps, the cookie isn't being retained on the browser. Any suggestions on why that could be?
Update2: The link provided by #Konrad Linkowski worked. When the axios request is made from the client, I needed the option "{ withCredentials: true }".
The error was on the client end. The express code functioned correctly. This link explains it: Does Axios support Set-Cookie? Is it possible to authenticate through Axios HTTP request?
My original call on the client side (using axios) was:
const res = await axios.post('/login', { ident: email, password });
Instead it should have been:
const res = await axios.post('/login', { ident: email, password }, { withCredentials: true });
My React Native app needs to use sessions for when users are signed in, but I'm not sure how to implement it. At first I thought I'd need AsyncStorage to store the session ID and attach it to each request to the server, but now I'm wondering if any additional code is required on the client side.
For example, I believe express-session sets a cookie automatically in the browser which means you just have to send the cookie. Is this the same for React Native/mobile applications? In other words, if I send a response that contains a cookie will that cookie automatically be attached to each future request, or do I need to store it somehow?
Have you tried axios ?, it automatically set the cookie it receive to client when you specify the option withCredentials: true.
example:
axios({
method: 'post',
url: '/api/auth/login',
data: {
username: username,
hashpass: hash(password)
},
withCredentials: true
}).then(res => console.log('login success'))
.catch(res => {
console.log('error')
})
i have a problem with my node.js nuxtjs app. I am sending requests with axios to api and on login request i get cookie normally. Everything works with recieving cookie from server, but when i GET another page, cookie isnt sending with it. Here are my OPTIONS on nodejs:
let options = { credentials: true, origin: "http://localhost:3000" };
app.use(cors(options))
Here is axios request:
export default async function ({ store, redirect }) {
try {
const res = await axios.get('http://127.0.0.1:5000/test', {
withCredentials: true,
credentials: 'include',
allowCredentials: true,
})
console.error(res)
store.commit('setAccess', res.data.access)
} catch {
return redirect('/register')
}
}
Any ideas? Thanks for your time.
To justify my mistake. I thought that nuxtjs middleware is running on client, which is not true. So cookie was not sent. I solved it by redirecting to auth page (which can be running some nice spinning wheel) and the submiting the refresh token to server and getting new one.
Thanks for your time and ideas !
For the authentication my server (nestjs) sends back a cookie with the token.
This is done like this:
#SetCookies()
#Post("account/signin")
async signin(#Body() dto: LoginDto, #Req() req, ){
const token = await this._authService.signin(req.user);
const options: CookieOptions = {
expires: moment().add(10, "days").toDate(),
signed: false,
secure: false,
sameSite: false,
httpOnly: true,
};
req._cookies = [
{
name: "SESSIONID",
value: token,
options: options,
}
];
}
And it works! At least postman shows me that the cookie was successfully created and send back.
But when Angular calls the API like this:
public signin(dto: LoginDto): Observable<any>{
return this._httpClient.post("http://localhost:3000/account/signin", {
username: dto.username,
password: dto.password,
}, {
withCredentials: true,
})
}
The set-cookie is send back visible in the network tab of the devtools.
Chrome devtools response headers
But the cookie is not stored in on the disk. The user is logged in but no cookie is persisted. EditThisCookie shows nothing and after a reload no cookie is send when a request to the server is made.
In other questions the problem got resolved by setting the secure attribute of the cookie to false, which i already tried.
I have setup cors with credentials = true on the server, without any errors on both sides while signing in.