Handling sessioning and middleware in a react SPA? - node.js

If I wasn't using react and was using express(nodejs) in the backend, this is what I would do for [an extremely simplified] auth system:
//Auth Middleware
const auth = (req, res, next)=>{
if(req.session.loggin_in===true){ next()}
else{ res.redirect('/login')}
}
//Endpoints
app.get('/', auth, (res, req)=>{ res.render('homepage')})
app.get('/login', (req, res)=>{ res.render('login')})
I know that you can use react routing to redirect the user to different pages, but how can you use middleware and session variables?
Do you have to send an http request for authentication from the client side to see whether the user is logged in? If this was the case, and supposing I wasn't logged in and tried to access the home page, I would first go to the home page before being redirected to the login page.
Thanks.

Related

Integrate existing Login Infrastructure from Node JS in Angular

I have in my backend server, which was built with Node JS, an authentication with the package "passport-azure-ad". I put the important elements of the code here in the post.
Basically, the process is that when I call the URI "localhost:3000/login", I start the authentication and (if you are not already logged in) the login window I get from Azure pops up. After the login, it routes to the callback URI.
I.e. I have the complete "login infrastructure" I need for my use case. However, now I built a frontend with Angular and unfortunately I have absolutely no idea how to best proceed to integrate the authentication I built in Node JS into my frontend (Angular)?
I want to check if there is a login when calling my frontend (localhost:4200), if not I want to route to 3000/login to trigger the Microsoft login window. I do this check in the backend with the ensureAuthenticated function. Now I wonder how to call all this from the frontend? It would be nice if someone could support me on this, any tips or any suitable sources would be greatly appreciated - thanks!
// session management
app.use(session({
resave: true,
saveUninitialized: true,
secret: process.env.COOKIE_SECRET
}));
app.use(passport.initialize());
app.use(passport.session());
// check if logged in
function ensureAuthenticated(req, res, next) {
if (req.isAuthenticated()) { return next(); }
res.redirect('/login');
};
// call azures login page
app.get('/login',
passport.authenticate('azuread-openidconnect')
);
// callback uri after authentication
app.post('/auth/oauth/callback',
function (req, res, next) {
passport.authenticate('azuread-openidconnect',
{
failureRedirect: '/failure',
}
)(req, res, next);
},
function (req, res) {
res.redirect('/account');
});
// protected ressource
app.get('/account', ensureAuthenticated, function (req, res) {
res.redirect('Login succesfull!');
});
// logout
app.get('/logout', function (req, res) {
req.logout();
req.session.destroy();
res.send('Ausgeloggt!');
});
When using an SPA like Angular, you can't no longer use this kind of authentication flow by using passport strategies to authenticate to third party endpoints like Microsoft/Google.
Instead, you start the OAuth2.0 flow from your Angular application straight to the Microsoft authentication endpoint. Tokens will be used for further authentication.
Some links:
Microsoft identity platform and OAuth 2.0 authorization code flow
Sign in users and call the Microsoft Graph API from an Angular single-page application (SPA) using auth code flow

How to make request to internal API with Express in node.js?

I have an API that I have previously defined like this.
app.get('/login', function(req, res){
//API implementation
});
I now have a second part of the API that needs to use the login API for verification.
app.get('/changePassword', function(req, res){
//Make request to /login endpoint and verify user credentials
});
How do I make a request to the login API from the change password function?
You could use the following function
res.redirect("/login");

How to send parameters with res.sendFile() while serving static content and access them in UI controller?

var claims = [];
app.get('/', ensureAuthenticated, function(req, res) {
claims = req.user['_json'];
app.use(express.static(path.join(__dirname, '/client/build')));
res.sendFile(path.join(__dirname, '/client/build/index.html'));
});
Above route and middleware authenticates the user that is trying to log in to my application, I want the logged in user details to be sent to UI along with res.sendFile and access them in my angular2 .ts file. How can I do so?
claims has the logged in user details
Using Express, you can't send a file and data at the same time. You will need to create two separate routes to get your user details and the webpage.
See this answer for more details : https://stackoverflow.com/a/31461737/4719679

Integrate steam authentication with front-end framework

I am currently developing an application with Node.js backend and vue.js as a frontend framework. As a log in for the application I am using passport-steam which works perfectly on the backend. A user is redirected to steam from the frontend in order to log in, the backend deals with the login and returns a req.user. Checking for user.isAuthenticated works on the backend. My question is how to pass that user information and the session that a user is authenticated to the frontend client ?
Server code:
app.get('/auth/steam/return',
passport.authenticate('steam', { failureRedirect: '/' }),
function(req, res) {
res.redirect('http://localhost:8080/#/index');
});
app.get('/account', ensureAuthenticated, function(req, res){
res.send({user: req.user});
});
When the user is successfully authenticated with steam he is redirected to the frontend --> localhost:8080/#/index which creates an axios request to localhost:/3001/account the backend whith the information for the steam account. Unfortunately nothing happens as the frontend request is not authenticated. Any suggestions ?
Thanks a lot !!

Passport authentication not working in sails.js application

I have a Sails JS application. I am trying to setup authentication using Passport.js authentication layer sails-generate-auth. I have configured my app by following the steps given in their documentation.
But when I lift my sails app, authentication is not working. I am able to access the controllers, even when I am not logged in (It's not redirecting to my login page).
I added a console.log statement in api/policies/passport.js as follows:
module.exports = function (req, res, next) {
passport.initialize()(req, res, function () {
passport.session()(req, res, function () {
res.locals.user = req.user;
console.log(req.user); // added by me
next();
});
});
};
Now, when I access controllers before login or after logout, its printing undefined. But when I am logged in, its printing my user data. Any idea why it is not checking for authentication?
I am using local authentication strategy and I have commented out all others (twitter, facebook...)
The above answer provides useful information. I want to elaborare on that.
sails-generate-auth, by default doesn't deny access to controllers if the user is not logged in. For that, you can create another policy in api/policies/. For example: create sessionAuth policy as follows:
module.exports = function(req, res, next) {
if (req.user) {
return next();
}
return res.forbidden('You are not permitted to perform this action.');
};
Instead of showing forbidden page, you can also render login page. For that you need access to AuthController.login. So, add the policies in config/policies as follows:
'*': ['passport', 'sessionAuth'],
'auth': {
'*': ['passport']
}
This helps to restrict access all the controllers except auth controllers such as login, logout and register, if the user is not logged in.
Passport doesn't have a policy to deny access to a controller. For this, you have to create another policy.
See this link for more details.

Resources