Upon reading up on web security, I found OAuth very interesting from a historical perspective. According to OAuth.net, and my own fuzzy memories, major websites like Yelp used to prompt users for their email and email password in order to log into the site. But I think we can all agree how shady that practice was--we don’t know how secure that other website is and if it’s hashing our passwords.
Fortunately, a bunch of engineers got together to devise a better solution and OAuth is one of them. With OAuth, a user is sent to another server to log in using trusted credentials such as Google, Facebook, GitHub, etc. Then once authorized, that third-party will redirect the user back to the original website as successfully logged into that website.
This is also useful for enterprise solutions such that teams of developers don’t have to worry about securing login credentials. If they build out their enterprise-wide OAuth login solution, then each team can use that one login solution as their own solution. This also makes it easier to add other OAuth login strategies (e.g. 2-factor) to that one solution, instead of every team adding it individually. For developers, there are several OAuth solutions such as JSO, OAuth2 Client, and PassportJS.
To experiment, I used Passport because I’ve seen a few popular developers use it. It offers “strategies” which are essentially those trusted credentials I mentioned earlier. I decided to go with a Google strategy (OAuth 2.0). The process is really simple: I provided a login route on an Express server and added a Passport middleware function to handle the Google authentication. Once the Google authentication is successful, Passport invokes a “verify callback” that the developer can write, which receives the (very limited) user data. Ideally, we’d want to store this data in our database as a starting point to improve the user experience, depending on the functionality of our website. Passport also supports sessions with cookies and thus uses a serializeUser function and a deserializeUser function. The deserializeUser function can perform a lookup in our database to ensure the user exists, and if the user does exist, it attaches the user’s data to the request object on a user property. This way, we can protect our routes which require authorization by adding middleware to check for the existence of the req.user object.
Here is the website I created while I was experimenting: https://oauth-with-passport.herokuapp.com
But the GitHub repo is way more interesting, haha...