Importance of Debugging
Tags: Token Authentication, Debugging, JavaScript, Express, Passportjs

Lessons I learned from a recent project I was doing which involved creating a token based authentication using passport-jwt .

Till now I always thought I could solve any code by throwing a bunch of `console.log` statements at it. In the off chance I had to apply debugger or set breakpoints, it was mostly to examine variables and mostly always for smaller code. Or code that I was quite familiar with (be it written by me or by someone else).

My token based authentication code which used passport-jwt was not working.

Yesterday I was stuck in a piece of code for a very long time. Way longer than I would care to admit.

How token based authentication works

A user registers (their details are saved in the Database and the browser receives a token)

This token needs to be included by the browser to access all `protected` routes (it can be included in the header or the request body). I was consulting a couple of tutorials and they were all using header for passing the token so I decided to follow the same approach.

Registering a user and sending a token back to the browser was working fine. Where I got stuck yesterday was when a user tries to access a protected route.

Since I had not created the Front end of the application yet, I was going to test this with Postman.

This whole fiasco started with me trying to debug my code and ended with me finding that header names are not case sensitive: [SO](https://stackoverflow.com/questions/5258977/are-http-headers-case-sensitive/5259004#5259004)

I’ve already disclosed the end of the story. But in this case, the lessons I learned during the road to discovering this statement is much more interesting.

The method to decode the token sent by request (this is an express middleware)

Decode the token so that you receive the payload that was used to create the token. There are libraries for it and I decided to use passport-jwt for this

Once the token is decoded, you get payload (userId or unique username etc. that which is used to create token in the first place) query the database to find the user corresponding to the token. If user exists, we have the correct token thus proceed to the next callback. If no user corresponding to the token, we do not proceed to the protected route and display ‘unauthorized’ (again passport does this)

The code for protecting a route with a token is as below.

I was testing my code using Postman where I was sending my json web token (created when a new user registers) as an Authorization header.

The code above looks quite straight forward.

When I sent a GET request without a header, I got no error message, and none of the console.log statements in my callback function new JwtStrategy(jwtOptions, callback) were hit. I was a bit confused but realised it was fine as long as the route was being protected.

Next up I made a GET request from Postman this time in my Headers, I added Authorization as a key and my value as the token I had received when I registered a user.

I was sure I would be able to view the protected route. I had sent the token and my implementation of token authentication was correct (verified from various sources).

But sadly I did not see the protected route and neither was I able to see any console.log statements in the callback function again.

I was perplexed. My header names were the same surely I should be able to authenticate. And even if I was not authenticated, I should see the error in callback statement.

It took a while for me to realise that my program was not hitting the callback and was exiting right after jwtOptions . I tried adding a bunch of console.log statements in a lot of place.

After that I tried to solve the problem by changing code at random. I added more middlewares (the one before requireAuth I’ve still left in the code to show that I tried to debug the problem in the worst case possible. )

I even started debugger using VS Code (but attached Chrome debugger instead of Node.)

Finally in one of the iterations of changing code, adding more debugger statements and adding more console.log statements I changed the following code snippet:

const jwtOptions = { jwtFromRequest: ExtractJwt.fromHeader('authorization'), secretOrKey: process.env.SECRET_KEY };

I made ExtractJwt.fromHeader('authorization')

Just changed the case of the request header key and the code worked.

Till this point I had spent hours trying to figure out what was going on with the code, how to use debugger in VSCode (had finally managed to attach Node as an environment but was not using debugging properly) and was just glad that it finally worked.

I closed the laptop and called it a day.

However when I got up today a few things were nagging me.

Why ‘authorization’ should work and not ‘Authorization’ was the first thing.

The second was my debugging skills. I had finally managed to start debugging in VS Code but did not utilize it properly.

So I decided I knew what the problem was (more or less) and wanted to use debugging properly to investigate this further.

How to start debugger in VS Code

To start debugger for node, select the debugging icon on left.

It opens the debugging panel.

Then there is a small ‘start debugging’ at the top, when you press that, we’re asked the context in which we want to debug.

I select Node because I want to debug an express app.

It runs code and breaks at first breakpoint.

In my case I just want to break when I trigger the route through Postman. So I just keep pressing continue in the debugging toolbar.

Once the application is no longer paused, I trigger the protected route through Postman. (And then the main debugging starts )

A point to note about VS Code debugger: If we change some variable in my code like I made ‘Authorization’ to ‘authorization’, we have to stop debugger and start it again. (May be I could make some changes to the configuration file to handle this but at this point I do not know how)

With node debugging I can break at a GET route or a POST route and then explore and check what’s going on (that was not happening when I had attached a Chrome debugger).

With correct code (that is ‘authorization’ in `jwtFromRequest: ExtractJwt.fromHeader(‘authorization’)` ), I kept stepping inside relevant code after I hit the breakpoint for ‘/protected’ route (because that’s the relevant place we need to check.)

After a lot of stepping inside the code, I did find a place in passport’s code where `token` was being extracted. Bingo that’s what I wanted. So I added a breakpoint there.

Next I changed ‘authorization’ which is the correct name for header to ‘Authorization’. Unfortunately had to restart the debugger.

But this time round I knew which was the relevant section of code where I needed to inspect my code further because I had a break point there. And bingo. No token when we name the authorization header as Authorization

I went to passport-jwt documentation and read a bit more and realised that authentication header names can be anything (this had not been my experience. After all when I used ‘Authorization’ instead of ‘authorization’, the app was not working)

So next up I changed the name of the header to Random both in my code and in my postman request and then restarted debugging. This time since I had a break point inside passport code where I knew I was supposed to break, I did not have to step through all that code and could just press the continue button till I reached the breakpoint in passport.

Then when I reached the point where token variable was being extracted by ExtractJwt I added variables to watch. It was here that I realised that though my header name was Random (in my code, in my Postman request and even in passport code) the request.headers did not have an attribute with name Random it had an attribute with name random .

Thus passport was trying to extract token from request.headers with name Random because that was the name I had specified for token in my code but there was no attribute with name Random .

At this point I realised that something was happening when Postman was setting the headers and I googled and found the link which I have linked in the beginning.

So basically the headers were being converted to lower case by Postman. Thus ExtractJwt could not extract token because it was searching for Random and not random .

I had used debugging before but with small applications that I had written. Mostly front end applications and never with an Express application before.

This was a good learning experience. A long time for debugging an error which I probably never would’ve found out if I had just used lower case letters to set authorization header key.