The Passport Authentication Control Flow
Introduction:
I am currently wrapping up the student portion of my journey as a
software developer and that means group projects, huzzah! Now, this is the time in which you sharpen your skills by getting things done with your peers with minimal involvement from program instructors, or at least that is the way it is done in our program. Anyway, while working in my current group, on a great project I might add, a groupmate asked me a question to which I felt I gave a subpar answer at best. So, in my quest to present a more informed answer in addition to satisfying my own standards of knowledge I decided to do some more research which lead to this blog. The question is coming, but first, we need to set the scene and explain the tech involved so no matter what level of developer you are currently, you can follow this story and possibly learn something constructive in the process. This story begins with authentication and since we were using node.js in our project that means I should briefly introduce passport.js.
What does is it mean authenticate?
User authentication involves obtaining unique identifying information from users traditionally including username + password, identification numbers, phone numbers, pin numbers, code words, secret handshakes, or email addresses. I snuck the secret handshake one in there just see if you were really reading, but in a physical setting that would definitely make the list. If you want a physical auth example for digit access, think of eye scans or thumbprint access now employed on phones.
Once these credentials are obtained and confirmed against a persisted list to be valid, your website will grant that authorized user access to previously restricted sections, services, or resources hosted on the site. Think of a situation in which you visited a site and were prompted to log in or create an account with a username and password. Well, my friend, that is authentication, and in this digital world, we have all experienced it.
Just to give you a visual reminder, the above picture is a basic example of the traditional authentication process that we are most familiar with. Now that we are clear on what it is to authenticate, let’s tackle the passport part.
What is passport.js and why use it?
Passport.js is an authentication library that allows developers to use external avenues or third-party entities for user authentication. Passport is middleware for Node.js based applications that serves the singular purpose of authenticating users to grant them access to an application. This allows a dev to basically outsource the task of collecting, persisting, and verifying user information to someone else and focus on creating an awesome application. This is great because it is one less user feature for the dev to have to map out, setup, and test. In my opinion, the biggest benefits of using Passport.js rather than setting up your own authentication are familiarity and trust. In the situation where a user is unfamiliar with a particular site and in turn, does not want to supply any personal information, Passport employs OAuth services from well know entities that will then be used to send identifying information to the less trusted sites granting users temporary access without exposing personal information or passcodes. Passport utilizes OAuth services with well-known sites like Facebook, Instagram, LinkedIn, Twitter, and Google to request certain information, not your password, known as tokens that will be used to authenticate and then authorize access to sites for a specific amount of time. Because users are more likely to already have an account with one of the trusted OAuth providers, this avenue of user authentication is becoming more popular. Each provider will require different authentication steps and so passport has created a different strategy for over 500 different OAuth providers from which developers can choose to incorporate into their site authentication process. To browse the full list visit http://www.passportjs.org/packages/.
Is he ever going to reveal the original question?
Now that the foundation is laid, and we understand what user authentication is along with how Passport.js fits into that process I feel I can move into the question that was asked to me. So, after we successfully incorporated Passport.js into our project and employed a Google OAuth strategy for users, and in the process of viewing the returned user profile object to implement other application features, I was asked if I knew the flow of the authentication middleware. I was able to use my intuition and a chain of console.log()
statements to give an answer but that wasn’t enough for me and so here we are.
What is the flow of information through the Passport.js chain of middleware?
First, in order to provide an OAuth service on your website, you must choose and configure the strategy. For our application, we choose the Google strategy and so below is how I configured and incorporated it into our application. I created a file titled passport-setup.js
in which I required all needed dependencies and configured the Google strategy.
passport-setup.js
// require passport library
const passport = require('passport');
// import googleStrategy from passport library
const GoogleStrategy = require('passport-google-oauth20');
// import db query functions from database/index.js
const { addUser } = require('../database/index');
// set up passport middleware to use google strategy in our project
passport.use(
new GoogleStrategy({
// options for the strategy, input clientID && clientSecret
callbackURL: '/auth/google/redirect',
clientID: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}, (accessToken, refreshToken, profile, done) => {
// passport callback function
// console.log('passport callback fired'); // indication that function fired
console.log('USER PROFILE', profile); // shows returned profile information
const { displayName, id, photos } = profile;
addUser({
google_id: id,
name: displayName,
profile_photo_url: photos[0].value,
})
.then((newUser) => {
console.log(`Created New User: ${newUser}`);
// completes the http request, and sends information to next function in middleware chain
done(null, newUser);
})
.catch((error) => {
done(error);
});
}),
);
When an unauthorized user visits and clicks a restricted link, they should be directed to a login page with authentication service options if more than one is set up or directly to the authorization endpoint. In the case of our application when users visited and clicked the login-in button in the navigation bar, they were redirected to google.com. The redirect was accomplished via an authentication route like the code snippet below.
authRouter.get('/google',
passport.authenticate('google', {
scope: ['profile'],
}));
Once the user has completed the authentication steps via Google they will be redirected back to our application at a specific endpoint. This was accomplished by specifying the callback route like below.
/**
* google callback route returns users to the home screen following google authentication
* utilize passport.authenticate() function to authenticate the user via google
* retrieve the users profile information
* finish by redirecting the user back to homepage "/"
*/
authRouter.get('/google/redirect', passport.authenticate('google'), (req, res) => {
res.redirect('/');
});
These three steps are going to serve as our top layer of the OAuth process because if you really examine each code example you will see portions that need deeper explanation and also require additional pieces of the puzzle to make them work. But from this top layer, we have directed the user to our OAuth provider, allowed them to log in, sent back the user profile information along with temporary access information which will be stored by our site. At this point, the user has been granted access to restricted service on our site and did not have to give any personally sensitive information.
Conclusion:
While authentication is a procedure we are all very familiar with these days, so is data security or lack thereof, and after learning more about the entire OAuth process I find it to be a simple aspect of UI/UX design that a developer can employ to make potential users more trusting of the applications they build. I want to continue our deep-dive into the OAuth process, so in the next installment we will unpack where to retrieve all the information needed to properly set up the OAuth strategy you want to employ, in addition to clarifying how the temporary access information returned is stored and then used on your site. I do hope you learned a little something new about the authentication process and that it sparks your own search for new things to incorporate into future projects. See you soon but until then….
Happy Coding!!!
Sources:
Passport Docs (www.passportjs.org)
Microsoft Docs (www.docs.microsoft.com/)
Learn OAuth 2 (www.tutorialspoint.com/oauth2.0/index.htm)
Top comments (0)