<Refactoring/> Authentication Checking Middleware. [Async/Await, Promises, JavaScript Shenanigans]

Asim Zaidi

My web agency, Tech Made has been developing MERN Stack web application to manage the growing student body club life for one of our clients, Make School Product College of Dominican University. The beta launch is about to happen and after some user testing here, the system may open up for any institution to use to better manage their student clubs. I’ll soon write more blog posts on the Clubs App.

Today, as the title says, we’re reviewing a cool refactor I recently implemented in the codebase of the Clubs App monolithic backend Node API. Before I dive into the technical details of my code refactor, I’d like to give you some context as to why. I already had my project working just fine so this was not a premature refactor/optimization. During the time of development, I needed to ship fast so I didn’t want to waste even 30 minutes trying over optimize when I knew I could write not the most dry code, but get it to work. I threw it on my Trello backlog and now here we are.

Let’s dive in. I was using JWT tokens stored in the session for user authentication. I had certain routes in my back end that only a user logged in should be able to do, some routes were only meant for club leader users, and some were meant for admins only. So each of these routes would first trigger the middleware to check for a user. I had 3 different authentication checking functions, called checkAuth, checkLeader and checkAdmin. All 3 of them damn near did the same thing to look at the jwt token, get the user id, find the user and continue with what was next in the route or else return an error. The only difference in checkLeader and checkAdmin was before setting req.user and returning next(), I checked if the user.type property was leader or admin, that is all. One line for like 20 extra lines of code in each function!

Here’s what the code looked like and what I refactored it into (The order of new and old code are in reverse order because of GitHub Gists ordering.)

💻✨🎯

So you can see in the old_checkAuth.js file there’s tons of repeated code happening. But what’s going on in the file below, new_checkAuth.js?

Allow me to walk you through this process of my refactor and finally fucking understanding async/await.

So at first, I legit just tried to get rid of all the code in checkLeader and checkAdmin. Then, simply calling checkAuth function from them and trying to access req.user to check their type. Once ran, my middleware threw a Reference Error, it did not know what req.user was. So calling another function from my other function wasn’t allowing me to keep the scope of the user variables. After some thinking, I decided to try and make the original function being called, checkAuth, return a Promise.

After running the code, something super strange happened. I still got th Reference Error and after some good old program tracing I realized that in my checkLeader function, even though I called that checkAuth function, my next line of code was ran before the checkAuth function finished resolving the Promise for me! “God damn it JavaScript”, I thought.

Finally, I realized I need to wait for that function to finish before executing the next line of code. Welcome, async/await! You can see in my new code how I made the checkLeader function asynchronous by adding the term async in front of function. Then on the checkAuth function call line I set user equal to whatever the function returns and I add await in front of it. So lessons learned here.

A JavaScript Promise must resolve or reject a value.

The word “async” before a function means one simple thing: a function always returns a promise. Even If a function actually returns a non-promise value, prepending the function definition with the “async” keyword directs JavaScript to automatically wrap that value in a resolved promise.

The keyword await makes JavaScript wait until that promise settles and returns its result.

await literally makes JavaScript wait until the promise settles, and then go on with the result. That doesn’t cost any CPU resources, because the engine can do other jobs meanwhile: execute other scripts, handle events etc.

It’s just a more elegant syntax of getting the promise result than promise.then, easier to read and write.

Await must only be used within an async function.

If we try to use await in non-async function, there would be a syntax error, you can’t async a regular function, you just can’t.

Asim Zaidi

Written by

Founder @Bondfire and @TechMade // Manager Sad Boy KJ. Gymnast, Spoken Word Rapper, Hackathon Hacker, University of Illinois Dropout. Currently, in the Bay.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade