Can't set cookies with req.cookies - node.js

req.login = (user) => {
const token = createJWTToken({ user });
console.log(token);
res.cookie('jwt', token, {
maxAge: 1000 * 60 * 15, // would expire after 15 minutes
httpOnly: true, // The cookie only accessible by the web server
});
req.user = user;
};
I use express, cookieParser is correctly used, but are never set.
Tried on other browser, and differents options.
Thanks.

req.cookies is an object and you can get cookie by using req.cookies object and if you need to set cookie then use res.cookie function(as you are doing in your code).
Note: Make sure req is a Request object and res is a Response object

Related

How can we store JWT token in Http only cookies?

I am creating login module.
User will enter Username and Password.
If user validate successfully then Server will return JWT token.
I will use the JWT token to validate the different API call in React js.
Now my concern is that I found some article regarding this then I found that We can use http only cookie. How can we implement httponly cookie method to store JWT ? Is it safe?
HttpOnly cookies are safe in that they are protected from browser access via the Document.cookie API, and therefore are protected from things like XSS attacks.
When your user is successfully validated, the server should generate a jwt token and return it as a cookie to your client like so:
return res.cookie('token', token, {
expires: new Date(Date.now() + expiration), // time until expiration
secure: false, // set to true if you're using https
httpOnly: true,
});
The cookie will be accessible via incoming http requests from your client. You can check the jwt value of the cookie with an authorizing middleware function to protect your API endpoints:
const verifyToken = async (req, res, next) => {
const token = req.cookies.token || '';
try {
if (!token) {
return res.status(401).json('You need to Login')
}
const decrypt = await jwt.verify(token, process.env.JWT_SECRET);
req.user = {
id: decrypt.id,
firstname: decrypt.firstname,
};
next();
} catch (err) {
return res.status(500).json(err.toString());
}
};
Reference for more details: https://dev.to/mr_cea/remaining-stateless-jwt-cookies-in-node-js-3lle

Sending cookies to browser fails in Express

I am able to successfully create my cookies and I can clearly see them in my console. Now the problem is that I want to send those cookies to the browser and I am not able to do that. When I open my Chrome and go to cookies they are not present there
I have set the secure option to false and also httponly to false but it does not seem to work
req.session.cart = cart;
var cookieValue = JSON.stringify([req.session.cart],{secure:false, maxAge: 180 * 60 * 1000, httpOnly: false });
var cookie = req.cookies.cookieName;
// no: set a new cookie
res.cookie('cookieName',cookieValue);
console.log('cookie created successfully');
// yes, cookie was already present
console.log('cookie exists', cookieValue);
res.redirect('/');
When I create the cookie they must appear in the browser
Like #Mike 'Pomax' Kamermans mentioned, I think this may have to do with res.redirect. Try adding them to your / route as well. Something like this:
// Requires cookie-parser
// https://expressjs.com/en/api.html#req.cookies
// https://github.com/expressjs/cookie-parser
app.post('/cart', function(req, res){
req.session.cart = cart;
var cookieValue = JSON.stringify([req.session.cart],{secure:false, maxAge: 180 * 60 * 1000, httpOnly: false });
var cookie = req.cookies.cookieName;
if(!cookie) {
res.cookie('cookieName',cookieValue);
console.log('cookie created successfully');
} else {
console.log('cookie exists', cookieValue);
}
res.redirect('/');
});
app.get('/', function(req, res){
if((typeof req.cookies == "object")&&(Object.keys(req.cookies).length>0)) {
console.log("Cookies are present");
// copy cookies from req to res
for(var o=0; o<Object.keys(req.cookies).length; o++) {
var key = Object.keys(req.cookies)[o];
res.cookie(key,req.cookies[key]);
}
}
res.status(200).send("OK");
});

How to read cookies on server-side with Express?

On my client-side I'am saving a token in the user's cookies :
this.socket.on('server:authentication', function(tokenObject){
if(tokenObject){
sessionStorage.setItem("token", tokenObject);
this.setState({ submitted: true});
}
}.bind(this));
Then I want to read that token on the server side, but when I do :
app.use(cookieParser());
app.use(function(req, res, next){
const { token } = req.cookies;
console.log(token);
...
});
I get "undefined" on the console. Same thing when I try console.log(req.cookies.token). How can I achieve that?
You need to set the cookie in your client-side code, you're currently setting is in sessionStorage, which is a different beast.
this.socket.on('server:authentication', function(tokenObject){
if(tokenObject){
document.cookie = 'token=' + tokenObject;
sessionStorage.setItem("token", tokenObject);
this.setState({ submitted: true});
}
}.bind(this));
See How to set cookie and get cookie with JavaScript

Renewing Cookie-session for express.js

I'm using the cookie-session module for Expresss.js to deal with sessions.
I would like the sessions to be renewed on every page load (or ajax call). That's how they usually work anywhere.
The documentation doesn't say a word about it.
I've tried doing this, but without success:
app.use(function(req,res,next ){
req.sessionOptions.maxAge = 20*1000;
return next();
});
I suspect that you are not sending the response cookie to the client. I solved the same problem (using express and cookie-session) with a middleware that sends a cookie containing a different value for each get:
var cookieSession = require('cookie-session')
app.use(cookieSession({
key: cookieKey,
secret: cookieSecret,
maxAge: 1 * 60 * 60 * 1000 // 1 hour (rolling)
})
);
app.get('*', function(req, res, next) {
// To update the session expiration time we need to send the new
// expiration in the response cookie.
// To send again the response cookie to the client we need to
// update the session object.
req.session.fake = Date.now();
next();
});
Indeed, if the session object does not change, cookie-session v. 1.2.0 does not set the Set-Cookie header to send the response cookie to the client.

How can I set cookie in node js using express framework?

In my application, I need to set a cookie using the express framework. I have tried the following code but it's not setting the cookie.
var express = require('express'), http = require('http');
var app = express();
app.configure(function(){
app.use(express.cookieParser());
app.use(express.static(__dirname + '/public'));
app.use(function (req, res) {
var randomNumber=Math.random().toString();
randomNumber=randomNumber.substring(2,randomNumber.length);
res.cookie('cokkieName',randomNumber, { maxAge: 900000, httpOnly: true })
console.log('cookie have created successfully');
});
});
var server = http.createServer(app);
var io = require('socket.io').listen(server);
server.listen(5555);
The order in which you use middleware in Express matters: middleware declared earlier will get called first, and if it can handle a request, any middleware declared later will not get called.
If express.static is handling the request, you need to move your middleware up:
// need cookieParser middleware before we can do anything with cookies
app.use(express.cookieParser());
// set a cookie
app.use(function (req, res, next) {
// check if client sent cookie
var cookie = req.cookies.cookieName;
if (cookie === undefined) {
// no: set a new cookie
var randomNumber=Math.random().toString();
randomNumber=randomNumber.substring(2,randomNumber.length);
res.cookie('cookieName',randomNumber, { maxAge: 900000, httpOnly: true });
console.log('cookie created successfully');
} else {
// yes, cookie was already present
console.log('cookie exists', cookie);
}
next(); // <-- important!
});
// let static middleware do its job
app.use(express.static(__dirname + '/public'));
Also, middleware needs to either end a request (by sending back a response), or pass the request to the next middleware. In this case, I've done the latter by calling next() when the cookie has been set.
Update
As of now the cookie parser is a seperate npm package, so instead of using
app.use(express.cookieParser());
you need to install it separately using npm i cookie-parser and then use it as:
const cookieParser = require('cookie-parser');
app.use(cookieParser());
Set Cookie?
res.cookie('cookieName', 'cookieValue')
Read Cookie?
req.cookies
Demo
const express('express')
, cookieParser = require('cookie-parser'); // in order to read cookie sent from client
app.get('/', (req,res)=>{
// read cookies
console.log(req.cookies)
let options = {
maxAge: 1000 * 60 * 15, // would expire after 15 minutes
httpOnly: true, // The cookie only accessible by the web server
signed: true // Indicates if the cookie should be signed
}
// Set cookie
res.cookie('cookieName', 'cookieValue', options) // options is optional
res.send('')
})
Not exactly answering your question, but I came across your question, while looking for an answer to an issue that I had. Maybe it will help somebody else.
My issue was that cookies were set in server response, but were not saved by the browser.
The server response came back with cookies set:
Set-Cookie:my_cookie=HelloWorld; Path=/; Expires=Wed, 15 Mar 2017 15:59:59 GMT
This is how I solved it.
I used fetch in the client-side code. If you do not specify credentials: 'include' in the fetch options, cookies are neither sent to server nor saved by the browser, even though the server response sets cookies.
Example:
var headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append('Accept', 'application/json');
return fetch('/your/server_endpoint', {
method: 'POST',
mode: 'same-origin',
redirect: 'follow',
credentials: 'include', // Don't forget to specify this if you need cookies
headers: headers,
body: JSON.stringify({
first_name: 'John',
last_name: 'Doe'
})
})
Set a cookie:
res.cookie('cookie', 'monster')
https://expressjs.com/en/4x/api.html#res.cookie
Read a cookie:
(using cookie-parser middleware)
req.cookies['cookie']
https://expressjs.com/en/4x/api.html#req.cookies
Setting cookie in the express is easy
first install cookie-parser
npm install cookie-parser
using middleware
const cookieParser = require('cookie-parser');
app.use(cookieParser());
Set cookie know more
res.cookie('cookieName', '1', { expires: new Date(Date.now() + 900000), httpOnly: true })
Accessing that cookie know more
console.dir(req.cookies.cookieName)
Done!
setting a cookie can be done as such:
res.cookie('cookie name', 'cookie value', [options])
where cookie_name is the name(String) of the cookie you wish to set, for example - "token", and the cookie value is the value(String) you wish to store in the said cookie.
as far as options go, you can read more about them here:
https://expressjs.com/en/api.html
one example of an option is 'maxAge' which indicates how long a cookie is valid, this is used for example when assigning an authentication token and you wish to limit the time a user can stay logged in before having to re-login.
Reading a cookie can be done as such:
req.cookies['cookie name']
which will return the value of the cookie.
Isomorphic Read cookie helper:
function getCookieValue(cookieName = '', cookie = '') {
const matches = cookie.match(`(^|[^;]+)\\s*${cookieName}\\s*=\\s*([^;]+)`)
return matches ? matches.pop() : ''
}
// Node with express:
getCookieValue('cookieName', req.headers.cookie)
// Browser:
getCookieValue('cookieName', document.cookie)
Write in Node with express:
res.cookie('cookieName', 'cookieValue')
Write in the browser:
function setCookie(
cname,
cvalue,
exdays = 100 * 365 /* 100 days */
) {
const now = new Date()
const expireMs = exdays * 24 * 60 * 60 * 1000
now.setTime(now.getTime() + expireMs)
document.cookie = `${cname}=${cvalue};expires=${now.toUTCString()};path=/`
}
// Example of usage
setCookie('cookieName', 'cookieValue')
If you have a problem with setting multiple cookies for one request
Try this way:
res.setHeader('Set-Cookie', [
`accessToken=${accessToken}; HttpOnly; Path=/; Max-Age=${60 * 60}; Secure=True;`,
`refreshToken=${refreshToken}; HttpOnly; Path=/; Max-Age=${60 * 60 * 24 * 7 * 2}; Secure=True;`
]);

Resources