Authentication without Passport - node.js

I'm using active directory to authenticate users, so I thought I didn't need to use Passport and that all I would need to do is after the password checks out is to create a global(?) boolean with res.locals to indicate that the user has been authenticated.
I've tried something like this in a controller function:
ad.authenticate(username,password, function(err,auth) {
//some of the things I tried unsuccessfully -- should be true after logged in
res.locals.auth = auth
app.locals.auth = auth //app not defined
})
However, I've discovered that when I call a later function checking if the user is logged in as part of middleware for a diff route, res.locals.auth and app.locals.auth are either false or undefined. I've tried setting both vars in my server.js file at the beg with the code below but that didn't work either...
app.use((req, res, next) => {
app.locals.auth = false;
res.locals.auth = false;
next();
});
So my question is, what var/where should I be saving the authenticated status? Or should I just use passport instead because there's some security concern that I was unaware of? What is the point of the isMemberOf in passport setup example?
https://www.npmjs.com/package/passport-activedirectory
All I want to do is just check user credentials and basically recreate req.isAuthenticated in Passport because I couldn't figure out how to use it because of the isMemberOf.

Usually the server sends back a token containing some useful data (user or session id, expiration date) either by cookies or by JWT (json web token).
Then a client puts the token into every request to the server . The server validates expiration date and handles requests.
Cookies will be put into a request by the browser automatically. JWT should be put into a request by your client code.

Related

express-session middleware to check authentication

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.

Check session is active in vue.js middleware

So basically I have an app that is separated between backend (node.js + express + express-sessions) and frontend (vue + node.js).
When the frontend calls my backend.host/login the backend creates a session and a session cookie is set to the user. The way I do it is the following:
req.session.userId = user._id;
In the frontend, I have a pinia store where I keep all my user state machine (login, logout,...). So a user logs in and the user object is stored in the store. Then all the pages can access that object.
But now, I would like to have something similar as the backend, so I can redirect the user when the session is not active or expired. So I would like to have a middleware that checks for the session cookie, and if it's not there, redirects the user to the index page. I can't rely on the store because every time I refresh the page it gets removed.
I saw some examples using JWT which they make a middleware like this:
export default function auth({ next, router }) {
if (!localStorage.getItem('jwt')) {
return router.push({ name: 'login' });
}
return next();
}
My problem is that I am not sure how to retrieve the session cookie from there, since nor next nor router parameters are the ones I need to.

Express JS routing based authentication

I have created node js app using express framework.
I have created middleware for restricting access to some routes.
Middleware actually works fine. but i have difficulties in displaying data.
Suppose In My app i have created route for display list of countries('/country/master')i.e html page which is using internally different/default route ('/country/') to get data from mongoDB.
In this case user will not able to see data cause i have not given permission to "/" routes. but i want to display data but not allow him to make use of "/" route to check data.
How can i deal with this case ????
The answer depends on your authentication strategy i.e. are you using session identifiers, access tokens, etc.
In either case I suggest that you break out the credential exchange (aka login) from the authentication. They should be separate middleware functions. Below is an example of what this looks like.
While this answers your question, specific to ExpressJS, it does leave out a lot of other details that matter when you are building an authentication system (like how to securely store passwords). I work at Stormpath, we provide user management as an API so that you don't have to worry about all the security details! It's very easy to integrate our API into your application, using the express-stormpath module. You'll have a fully featured user database in minutes, without having to setup mongo or a user table.
All that said, here's the example:
/* pseudo example of building your own authentication middleware */
function usernamePasswordExchange(req,res,next){
var username = req.body.username;
var password = req.body.password;
callToAuthService(username,password,function(err,user){
if(err){
next(err); // bad password, user doesn’t exist, etc
}else{
/*
this part depends on your application. do you use
sessions or access tokens? you need to send the user
something that they can use for authentication on
subsequent requests
*/
res.end(/* send something */);
}
});
}
function authenticate(req,res,next){
/*
read the cookie, access token, etc.
verify that it is legit and then find
the user that it’s associated with
*/
validateRequestAndGetUser(req,function(err,user){
if(err){
next(err); // session expired, tampered, revoked
}else{
req.user = user;
next();
}
});
}
app.post('/login',usernamePasswordExchange);
app.get('/protected-resource',authenticate,function(req,res,next){
/*
If we are here we know the user is authenticated and we
can know who the user is by referencing req.user
*/
});
You can positioning of middleware in you app.for example:-
app.get('/country/master',function(req,res){
})
app.use(function(req,res){
your middle ware for providing authentication
})
// other routes where authentication should be enabled
app.get('other urls')

Node, express, passport - updating session after updating record

I'm rather new to node, I have started writing a small app and am working on my user auth and profile. I'm using express, passport and ejs. I've got passport working and have my user redirecting to a profile page that requires additional data before the user begin's to use the application. My question is:
What's the proper way to update the user's session (created at passport.authentication) when a user updates their profile data? I would like to update the user session in order to hit it rather than the data base for basic user data.
If your using express you have middleware that looks like:
function (res, req, next){}
When you get session data you can add it to the req object.
function (res, req, next){
// get the session here...
req.session = session;
}
Then any other middleware will have access to the req.session object which will contain the user's session.

Create session only after successful authentication in express

I have a requirement to create a session only after successful authentication.
I was able to create redisStore based session using express middleware, but it creates session when the first request comes to server.
But how I can create session only after successful authentication.
I googled somewhat, and foundreq.session.regenerate() (but I found the issue as below mentioned in this thread:
Regenerate session IDs with Nodejs Connect)
But in regenerate case also, it creates a fresh one, assuming old one is created already, and is created with same parameter.
So there is any other way to create a new session ID only after successful authentication..?
You may be conflating the idea of a session with the idea of an authenticated session.
It's normal for all users to have a session - even the anonymous, not-yet-logged-in users. The difference between this and an authenticated session is just that, locally on your web server, you specify that a particular user has been authenticated.
For example, once you authenticate someone, you can set:
req.session.isAuthenticated = true;
Then, when rendering pages, your controllers can do something like
function(req, res, next) {
if (!req.session.isAuthenticated) return res.redirect('/login');
res.render('appPage');
}
This might not be the exact answer you're looking for, but I'll answer the title for future readers:
From experimenting with my application, I've noticed that express-session sets the session cookie only if you manipulate the session object.
For example consider the below code:
app.post('/login', function (req, res) {
var authenticated = false;
if (req.session.authenticated) {
// session cookie is already set
authenticated = true;
} else if (/*validate the user here*/) {
console.log(' authenticating');
authenticated = true;
// if below line executes, the response will have Set-Cookie header
req.session.authenticated = authenticated;
}
res.json({
status: authenticated
//if --^ false, no session cookie will be set since we didn't manipulate session object
});
});
Even though a request creates a session object in memory for us to use, the Set-Cookie header seems to be sent only if we manipulate (or tamper with?) the session object created.
Unless we sent the Set-Cookie header along with the response and session id is stored in cookie at client side, I wouldn't consider it as an established session and worry about it.
Hope it helps.
Side note: This is the case of a cross-domain ajax request, might be different for normal http request, perhaps someone can confirm this

Resources