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 !
Related
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.
i have an issue when trying to send the cookies from browser to nextJs server
first let me describe the issue :
my backend API is built with Nodejs and express, the frontend is
handled by Nextjs , when the user try to login the token is stored as
an httpOnly cookie ,to get the loggedin user i must send the cookie
from my frontend to my backend so i do that through nextJs
getServerSideProps function with the help of
Context.req.headers.cookie in order to sent this token to my nodeJs
backend.
this is the login controller (backend):
exports.login = catchAsync(async (req,res,next)=>{
// SOME CODE
const token = jwt.sign({id: user.id}, process.env.JWT_SECRET);
const cookieOption = {
expires: new Date(Date.now() + process.env.JWT_COOKIE_EXPIRES_IN*24*60*60*1000),
httpOnly: true,
secure : true,
sameSite: 'none',
// domain: '.herokuapp.com'
};
res.cookie('jwt', token, cookieOption);
res.status(200).json({
status: 'success',
data: {
user
}
})
});
and this is my getServerSideProps function in which i try to send the token from nextJs to nodeJs server:
export async function getServerSideProps(context){
console.log(context.req.headers.cookie) // EMPTY OBJECT!
console.log(context.req.cookies) //EMPTY OBJECT TOO
let user
try{
const res = await fetch(`${url}/users/isLoggedin`, {
method: 'GET',
credentials:'include',
headers: {
'Access-Control-Allow-Credentials': true,
Cookie: req.headers.cookie
},
})
const data = await res.json()
if(!res.ok){
throw data
}
user = data
}catch(err){
return console.log(err)
}
return {
props: {
user,
}
}
}
i can send the token from browser directly to nodeJs (client side) but i can't send the token from the browser to nextJs server i don't know why, i have tried many solutions but no ones workes for me .
note: both backend and frontend are deployed to heroku
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.
In my NodeJS Express app (built with feathers); I'm trying to work with cookies with client-side fetch from client javascript. I have Express using the cooke-parser middleware.
I have tried setting the credentials header to same-origin, but that has stopped working (it worked fine yesterday, and a few times today... but I've been trying to build up the cookie to what I need and it just doesn't seem to reliably work).
This is my test express route:
app.post('/setjwt', (req, res, next) => {
res.cookie('acokie', 'lol');
res.status(200);
res.send();
});
I'm using fetch in chrome dev tools console to test sending requests like so:
fetch('/setjwt', { method: 'POST', headers: { credentials: 'same-origin' } } );
These are the headers:
But there is no cookie listed in the Application tab nor available in document.cookie.
The reason I have this route is two fold:
Understand how cookies work and interop with Express.
Get rid of this hacky route altogether and get the headers/environment set up correctly so my feathers authentication service's Set-Cookie response header is respected by the browser.
The feathers client on the login page is set up with fetch as its rest implementation, and I can set
fetch('/setjwt', { method: 'POST', headers: { credentials: 'same-origin' } } ); won't work.
The credentials property cannot be specified like that with fetch. The correct code is:
fetch(
'/setjwt',
{
method: 'POST',
credentials: 'same-origin',
headers: { whatever: 'somevalue' }
});
As for setting it up so that the feathers authentication service would work, again, it's not a normal header so brushing up on the documentation hopefully might yield something useful, but I don't think the feathers-rest wrapper over fetch supports passing non header options.
I use fetch() to send a post request for logon,
after server validation, I use req.session.account = account[0]; to save the account information to the session and return a redirect URL,
But after the redirect, the account information in the session is lost, why is that?
If you would have some example code, that would help us track down the problem. My first idea would be to make sure express-session is properly configured:
var app = express();
var session = require('express-session');
app.use(session({
secret: 'ibfiyegfiyegfe' // Secret is a required option.
}));
For futher configuration options, see the express-session repository.
EDIT: Based on the additional information, I'm guessing you have express-session configured to also use cookies for managing the sessions. What this means, is that for every HTTP request Express sends a response back that includes a cookie. jQuery based AJAX calls will ignore the response cookie however, which causes consecutive requests to Express to look as if you never logged in. To allow saving the cookie when performing AJAX requests with jQuery, use the xhrFields field to enable withCredentials:
$.ajax({
url: "http://....",
type: "POST",
xhrFields: {
withCredentials: true
},
data: {username: username, password: password},
success: function(responseBody) {
console.log("success!");
},
error: function(responseBody) {
console.log("error!");
}
});
Hope this helps.
Sorry to everyone, I don't making the question clear.
I use the fetch() method send a request to logon.
fetch('/logon', {
method: 'post',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: JSON.stringify({
account: account,
password: password
})
}).then(function(response){
return response.json();
}).then(function(json){
if(json.success == 1){
window.location.href = json.redirecturl;
}else{
indexDispatcher.dispatch({
actionType: 'logonFaild',
errorInfo: json.msg
});
}
});
And the server's response is just simple JSON:
if (err) {
consoloe.log(err);
} else {
req.session.account = account[0]; //save account to session
var redirecturl = '/team/' + team[0].id;
console.log("account添加到session了");
res.json({
success: 1,
redirecturl: redirecturl
});
}
But when the client get the redirecturl and redirect, the account data is lost,so it will occur a TypeError: Cannot read property 'id' of undefined(id is saved in req.session.account).
But when I use jquery $.ajax relpace fetch, it works well. I don't know the reason.
I had the same experience like you hundreds of times which I finally found the problem. You don't need to worry if cookies enable or disable.
You just have to re-declare parts of your scripts (variables-the data which you want to display) in a if else condition.
Just redeclare the same thing using !isset and then else with the same variables mentioned twice in the if else condition, if you understand what i mean.
It will call back the same variables over and over. And make sure start session is above the page. no need to worry about headers or white lines, it has actually nothing to do with it.
I've tried it a million times. You don't need to bother using ajax etc. PHP can do almost everything. cheerio.