Express session don't persist - node.js

I was making a React project, and I was using Express for backend. I set http://mini-api.moonlab.ga as a virtual host for Express server.
I sent a HTTP Request to express server with Fetch:
fetch("http://mini-api.moonlab.ga/login/", {
credentials: "include"
})
and as I expected there was a CORS error. So I installed cors package, and I set code like this in Node.js:
app.use(cors({
origin: true,
credential: true
}));
And I respond to client from server like this:
app.get("/login", (req, res) => {
const session = req.session;
if (session.miniAccount == undefined) {
session.miniAccount = Math.floor(Math.random() * 1000000);
}
res.writeHead(200, {"Access-Control-Allow-Credentials": true});
res.write(String(session.miniAccount));
res.end();
})
After I did like this, there wasn't any CORS error, but the session don't persist. When I send a request again, the session data keeps changes.
Well how to make session persist?
Server's session code:
app.use(express_session({
secret: secret.app_key,
resave: false,
saveUninitialized: true
}));

You may try setting a maxAge value inside cookie
...
const session = require("express-session");
...
app.use(
session({
secret: secret.app_key,
resave: false,
saveUninitialized: true
cookie: {
maxAge: 3600000 //session expires in 1 hr
}
})
);

I solved it myself by editing package.json.
I added "proxy": "mini-api.moonlab.ga" in package.json.
Than I edited fetch().
previous
fetch("http://mini-api.moonlab.ga/login")
new
fetch("/login")
And it worked.

Related

connect.sid not getting stored in cookie

I have a node express application.
const session = require('express-session');
const config = require('config');
var MemoryStore = require('memorystore')(session);
module.exports = function (app) {
app.use(express.json());
app.use(
session({
saveUninitialized: false,
cookie: { maxAge: 86400000 },
store: new MemoryStore({
checkPeriod: 86400000
}),
resave: false,
secret: config.get('Storagehash')
})
);
app.use('/api/auth', users);
}
I have separated auth route and put it in a separate file like this. When I do console.log(req.session) I'm getting proper output.
const router = express.Router();
router.post('/', async (req, res) => {
....
req.session.isAuth = true;
console.log(req.session);
req.session.customerID = customer;
res.send(token);
}
But when I'm looking in the cookie tab, connect.sid is not getting inserted there.
Do you have a frontend application? If so, whenever you send a request to your backend you need to include withCredentials: true in your request. This will send the cookies to your backend. If you are using axios to make requests it can be done like this:
(Assuming your port is 5000)
axios.post("http://localhost:5000/api/auth/", {}, { withCredentials: true });

Res header contaisn set Cookie but browser isn't storing it

I'm using express-session to store session cookie. I can see Set-Cookie connect.ssid under the response header but for some reason it is not getting stored in the cookie.
I'm wondering if this is a CORS issue, my app file looks like this. Should I change something here to make it work.
const session = require('express-session');
const config = require('config');
var MemoryStore = require('memorystore')(session);
module.exports = function (app) {
// app.use(
// session({
// secret: 'key sign',
// resave: false,
// saveUninitialized: false
// })
// );
app.use(express.json());
app.use(cors({ credentials: true }));
enter code here
app.set('trust proxy', 1);
app.use(
session({
saveUninitialized: false,
cookie: { maxAge: 86400000 },
store: new MemoryStore({
checkPeriod: 86400000
}),
resave: false,
cookie: { secure: false },
secret: config.get('sessionStorage')
})
);
app.use('/api/users', users);
Here is how I fixed this.
Add SSL to both frontend and backend.
If it is self-signed, ensure browser trust it. For example, if you're using mac, go to keychain, select specific certificate and select always trust option.
Restart the system. Only then SSL will be properly set otherwise there would still be insecure badge in the navigations.

Nodejs/Express/Cookies: how do you set signed cookies with a secret

In my directory i have app.js And Index.htmml ; I am trying to set cookies from App.js; I have tried:-
var express = require('express'),
app = express(),
http = require('http'),
cookieparser = require ('cookie-parser'),
httpServer = http.Server(app);
app.use(express.static(__dirname + '/data'));
app.get('/', function(req, res) {
let options = {
maxAge: 60000, // would expire after 1 minutes
httpOnly: true,
signed: true ,
secret: 'secret'
}
// Set cookie
app.use(require('express-session')({ secret: 'keyboard cat', resave: true, saveUninitialized: true }));
res.cookie('cookieName', 'Success', options)
res.sendFile(__dirname + '/index.html');
});
app.listen(8080);
When i run app.js from Cmd It dissappoints me with this error
Thanks in advance for help
Error: cookieParser("secret") required for signed cookies
You need to specify a secret key which will be used while signing the cookie.
You can do this by adding the following line to your code.
app.use(cookieparser("secret"));
According to the snippet, you are using the express-session module like so:
app.use(require('express-session')({ secret: 'keyboard cat', ... }));
That is already saying that you want cookies to be signed. Therefore, in your cookie options you can remove the option signed: true since it will be redundant.
And on a last note, you need to improve that code.

How can I get the current session information from express-session?

I am using express-session to store my session data for my Node app as follows:
import express from 'express';
import session from 'express-session';
import connectRedis from 'connect-redis';
const app = express();
const RedisStore = connectRedis(session);
app.use(session({
secret: 'keyboard kat',
store: new RedisStore({
url: '//redis:6379',
}),
resave: false,
saveUninitialized: false,
proxy: true,
cookie: {
secure: true,
},
}));
and I'm trying to get the information of the current session in the browser. I tried typing session in the console to no avail. Similarly, adding a console.log(session) below where I set up use of the session in the app doesn't work. How can I get the current session information from express-session?
You can simply use your app with a function that references the session
app.use(function (req, res, next) {
console.log(req.session)
})
but it will print to the command line running your Node server rather than the console of the browser.

Node-Client-sessions vs express-session

I have this Node API that frontends a backend OAuth server. At the end of the SAML OAuth dance, I set the Bearer Token in a browser cookie.
// 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();
});
app.use(express.static(__dirname + '/public'));
Now I was introduced to a fancy NPM which does pretty much the same thing https://github.com/mozilla/node-client-sessions
While I was almost inclined on using this NPM, I bumped into express-session. https://github.com/expressjs/session - this is for server side sessions. But this also sets a cookie
var express = require('express');
var session = require("express-session");
var app = express();
app.use(session({
resave: true,
saveUninitialized: true,
secret: 'ABC123',
cookie: {
maxAge: 60000
}
}));
app.get("/test", function(req, res) {
req.session.user_agent = req.headers['user-agent'];
res.send("session set");
});
If my need to set only a bearer token in the browser cookie for subsequent API calls, which option should be my choice?
express-session is my go to.
If you look at what it took to accomplish the same thing with the two different methods, I think the answer is clear.
If all you want to do is set a client cookie that will enable the server to correctly authenticate future requests, express-session is awesome.
Here is an example set from another question I answered that uses MongoDB as a backend to store your sessions:
'use strict';
var express = require('express'),
session = require('express-session'),
cookieParser = require('cookie-parser'),
mongoStore = require('connect-mongo')(session),
mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/someDB');
var app = express();
var secret = 'shhh';
app.use(session({
resave: true,
saveUninitialized: true,
secret: secret,
store: new mongoStore({
mongooseConnection: mongoose.connection,
collection: 'sessions' // default
})
}));
// ROUTES, ETC.
var port = 3000;
app.listen(port, function() {
console.log('listening on port ' + port + '.')
});

Resources