Continued my web security studies. Finally got through the storm and can understand how PassportJS works with or without Sessions. The implementation is not that difficult but I guess I struggled to understand the explanations provided in the documentation. After re-reading the text and comparing the example code snippets in the docs to the example implementation from The Odin Project and the PassportJS playlist I was able to fill in the gaps.
I am now working on properly documenting this information in a way that I can easily understand the next time I have some doubts or need to review. It is crucial to do this while I still have the information fresh in my mind. In the past I would neglect writing notes because I thought it was a waste of time but now I realize the importance. Memory is a fleeting things when learning so much all the time. Especially with technical knowledge. There is key information that I keep on hand but a lot of the things I learn are syntax related and should not be memorized tbh. It is a waste of time to focus so heavily on memorizing some commands that are not even used that often. But notes help to give you the best of both worlds. Tailored documentation that makes it easy for you to refer back to it in the future.
TLDR;
Okay, so here are the highlights of what I did:
- Backend -> Continued studying the concepts mentioned in the web security section. Made some really good progress with understanding how PassportJS works as a framework. I am working on compiling all the information in this docs page as well as all the other examples and sources to construct my own notes that ensure this framework is clear and easy for me to use in the future.
Rough Notes on PassportJS
Overview
Passport is authentication middleware for Node.js. It is designed to serve a singular purpose: authenticate requests.
Passport works to separate the overhead involved with authentication by providing a framework that divides concerns into:
- Middleware
- Strategies
- Sessions
while delegating unrelated details such as data access to the application itself. Whether you are building a new application or working on an existing one, this separation of concerns makes Passport extremely easy to integrate.
Passport is authentication middleware for Node.js. Extremely flexible and modular, Passport can be unobtrusively dropped in to any Express-based web application. A comprehensive set of strategies support authentication using a username and password, Facebook, Twitter, and more. – Passport Website 2022
Middleware
Passport is used as middleware within a web application to authenticate requests. Middleware was popularized in Node.js
by Express
and its even more minimalist sibling Connect
.
The following code is an example of a route that authenticates a user with a username and password:
app.post('/login/password',
passport.authenticate('local', { failureRedirect: '/login', failureMessage: true }),
function(req, res) {
res.redirect('/~' + req.user.username);
});
In this route, passport.authenticate()
is middleware which will authenticate the request. By default, when authentication succeeds:
- The
req.user
property is set to the authenticated user - A login session is established
- The next function in the stack is called
The next function called in the stack is typically application-specific logic which will process the request on behalf of the user (i.e. Once the user is authenticated successfully perform the request handling and send the desired response back to the browser/client).
When authentication fails, an HTTP 401 Unauthorized
response will be sent and the request-response cycle will end. Any additional functions in the stack will not be called. This default behavior is suitable for APIs obeying representational state transfer (REST) constraints, and can be modified using options.
In traditional web applications, which interact with the user via HTML pages, forms, and redirects, the failureRedirect
option is commonly used. Instead of responding with 401 Unauthorized
, the browser will be redirected to the given location with a 302 Found
response. This location is typically the login page, which gives the user another attempt to log in after an authentication failure. This is often paired with the failureMessage
option, which will add an informative message to the session about why authentication failed which can then be displayed to the user.
The mechanism used to authenticate the request is implemented by a strategy. Authenticating a user with a username and password entails a different set of operations than authenticating a user via OpenID Connect. As such, those two mechanisms are implemented by two different strategies. In the route above, the local strategy (from the npm
package called passport-local
) is used to verify a username and password.
Strategies
Strategies are responsible for authenticating requests, which they accomplish by implementing an authentication mechanism. Authentication mechanisms:
- Define how to encode a credential, such as a password or an assertion from an identity provider (IdP), in a request.
- Specify the procedure necessary to verify that credential.
If the credential is successfully verified, the request is authenticated. There are a wide variety of authentication mechanisms, and a corresponding variety of strategies. Strategies are distributed in separate packages. To use them for authentication we must:
- Install the package containing the strategy (Generally using
npm
just like any other package). - Configure the strategy manually by calling the strategy constructor with our desired customizations.
- Register the strategy in PassportJS by passing the configured strategy in the
passport.use(strategy)
method.
Once these three steps are executed the strategy can be used to authenticate HTTP requests by using the configured PassportJS middleware function in routes for our server-side application.
Goal For Round 8 of the #100DaysofCode Challenge
This is my eighth round of the “#100daysofcode” challenge. I will be continuing my work from round five, six, and seven into round eight. I was working through the book “Cracking the Coding Interview” by Gayle Laakmann McDowell. My goal was to become more familiar with algorithms and data structures. This goal was derived from my goal to better understand operating systems and key programs that I use in the terminal regularly e.g. Git. This goal was in turn derived from my desire to better understand the fundamental tools used for coding outside of popular GUIs. This in turn was derived from my desire to be a better back-end developer.
I am currently putting a pause on the algorithm work to build some backend/full stack projects. I primarily want to improve my skills with the back-end from an implementation perspective. I have improved tremendously in terminal and CLI skills but I lost focus due to how abstract the algorithm concepts got. I wanted to work on things that were more tangible until I can get to a position where I could directly benefit from improving my algorithm skills and theoretical knowledge. So that’s the focus right now. Build my backend skills and prove my full stack capabilities by building some dope projects.
Again, I still have no idea if my path is correct but I am walking down this road anyways. Worst case scenario I learn a whole bunch of stuff that will help me out on my own personal projects. Best case scenario I actually become one of those unicorn developers that go on to start a billion dollar company… You never know LOL.