If I am using client-sessions in NodeJS and wish to completely remove a session, how do I go about doing so? It seems that calling reset() just clears the session contents, effectively issuing a new session and updating the cookie with a new, extended expiry.
In this case, I wish to remove the session cookie altogether under certain circumstances (logout, etc.). Does anyone have any tips on how to do so?
In a router like so...
router.get('/logout', function (req, res, next) {
var session = require('client-sessions');
req.session.reset();
res.redirect('/login');
});
Try using
req.[session].reset()
where [session] is the name of your cookie.
Related
I have a question about the usage of sessions with express-session. I really don't understand how the sessions are secure. For example in the following official guide: https://expressjs.com/en/resources/middleware/session.html they create a middleware to check if the user is authenticated:
// middleware to test if authenticated
function isAuthenticated (req, res, next) {
if (req.session.user) next()
else next('route')
}
But I don't understand, why isn't this middleware checking that the session is in fact, inside the DB? An attacker could just modify the session cookie with random values and there would be still some value in the user field, even if it's a garbage value, no? So the function still would think this is an authenticated user.
Why is this not possible?
In my case, I am setting the userId in the session and then every time someone makes a request, I retrieve its userId, but I do not understand, what if someone modifies the cookie and gets a random userId value? My application will think this user is authenticated, correct?
why isn't this middleware checking that the session is in fact, inside the DB?
This check, which you rightly expect to be done, is already done before, in the express-session middleware: This looks up the value of the session cookie in the session storage (which can be a database) and populates req.session accordingly. Since the value of the session cookie is unguessable, an attacker who puts in a random value, will make req.session undefined, and the isAuthentication check will fail, as it should.
I have a MERN stack blog app that I'm making as a learning exercise. I'm relatively comfortable on the front end but have limited experience in node. I'm adding authentification after following a couple tutorials to get this far. I'm using passport.js as a framework to make a request to Google, get back an id and save as session info. However, after logging in, req.session is empty when making a post request, even though I can see a cookie in the dev tools.
I'm using bcrypt's hash to obscure the actual id, but that may not be best practice.
in blogAuth.js: req.session is defined.
bcrypt.hash(req.user._id.toString(), saltRounds, function(err, hash) {
req.session.user = hash;
//session is set here.
console.log(req.session); res.redirect(http://localhost:8080/articles/loggedIn);
});
but in api/articles.js: req.session is empty
router.post("/", (req, res, next) => {
const { body } = req;
// session is empty here. Why?
console.log(Session user, ${req.session.user});
console.log(req.session);
I have tried:
Including proxy in the client package.json:
express req.session empty with cookie-session
using withCredentials set to true when sending the POST from the
client:Node + Express + Passport: req.user Undefined
Rearranging the order of middleware: Routes must always come
afterward, but I feel like I'm doing this blindly and it usually results in an error
Here's some of the relevant files:
Server side:
- app.js
- blogAuth.js
- passport.js
- api/articles.js
Client side:
- the POST req
Entire project
I believe this is an issue with ordering. What is a good way to ensure that I order my middleware correctly? Or if the order looks correct, where else could this issue becoming from?
You are trying to use cookie-session as well as express-session. Since both of them will try to control the fate of req.session object, you will end up with empty session always.
Just remove one of them, and your session will be persisted.
I have a simple authentication system built on Passport.js on top of Node.js. I have a use case where I need to persist Organisation ID in the session which is to be updated on hitting of a particular route.
I did this using the middleware:
app.use('/switchOrganization',function(req, res, next) {
if(req.user) req.session.passport.user.activeOrg = 'my org';
next();
});
But this doesn't persist the data in other routes:
app.route('/someRoute').post(function(req,res){
console.log(req.session.passport.user);
});
It doesn't contains the 'activeOrg' value. Where I am going wrong?
The user object is deserialized into req.user in the deserializeUser function. This happens on each request. So if you make change to req.user in one of the route handlers, and expect it to be persisted for the route handlers that follow it, it'll only be the case for that particular request. If /someRoute is requested anew, it will not have the the changes you made in another route which wasn't invoked in the new request.
You should instead persist the changes to database so that when the deserializeUser function is called for the next request, it'll have your data from the beginning.
I am using redis sessionStore. And if I write to req.session, then data persists on redis store:
req.session.access_token = result.access_token;
req.session.refresh_token = result.refresh_token;
req.session.instance_url = result.instance_url;
Redis Screenshot
I believe I have configured everything correctly:
app.configure(function() {
app.use(express.cookieParser('secret message')); // secret it set here in new version of express or connect
app.use(express.bodyParser());
app.use(express.session());
app.use(passport.initialize());
app.use(passport.session());
});
When the request is made to "login" with the correct credentials:
app.post('/api/login', passport.authenticate('local'), function (req, res, next) {
console.log(req.session.passport); // {"user":"5259f2739d4323000a000003"}
});
req.session.passport is populated:
"passport": {"user":"5259f2739d4323000a000003"}
However, when a call is made to:
app.post('/api/checklogin', function (req, res, next) {
console.log(req.session.passport); // {}
})
req.session.passport is lost:
"passport":{}
Both times, req.session looks like this:
{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"passport":{}}
** Passport object is obviously different though, as described above
I assume I have configured serializeUser correctly, because it correctly sets this property.
I am not completely sure how Passport creates session cookies, and how these cookies can persist.
I assume that req.session.passport is supposed to retain the user property, but it seems that the Passport object either:
Resets on every call
Does not actually save the Passport property in the session
The session is never created
I fear that I may be overlooking something large -- possibly something that I may need to do that Passport doesn't handle directly for me.
I do not know of any way to test if the session is created by Passport.
Any advice or help is really appreciated. This has been a multiple day struggle.
Are you using a cluster setup? If so, you need to stop using the default MemoryStore, and switch to something like connect-redis, so different instances of your app can access the shared session data.
I cannot seem to figure a way to prevent Express/Connect to create sessions until I have a valid log in from the user.
The problem especially arises when using a DB-Backed Session Storage and calling the REST Services from non-browsers as in such cases, the Connect Session Object will create a new Session for each request which I do of course want to prevent.
However, I do need sessions whenever the user is authenticated as I am using Passport.js for authentication which requires sessions as well as I do require it to load session data from sent cookie information.
Looking at the source of the Connect Session Code, it seems it is always creating a new Session if none got sent from client without any option to prevent it..?
thanks
Alex
If you can easily identify calls to your API at query time you could do something like this:
app.use(function(req, res, next){
if ( req.path.indexOf("/api") == 0 ) return next();
else return express.session()( req, res, next );
});
This way the session middleware is only included if the request URL doesn't match some condition. I haven't tried this in anger though, so you might want to consider initialising express.session() outside the function, and make sure there aren't any other repercussions.