Auth token management with Node.js Observer pattern

Consider the following situation where you are getting data from a third party server using the authentication token.

  1. You request the auth token
  2. Auth token received.
  3. Send request with auth token
  4. Received the desired response.

And once the token expires, we fetch a new one, save it and keeps on making this new request with this new auth token.

Here is the sample code with for request.

Below is our mocked authentication system

Now if we run both apps on respective port (8080 and 8081), and run this test script

we would received the following logs at the services as expected

// serviceHandler output
{“newToken”:”def”}
No need for new request
No need for new request
No need for new request
No need for new request
No need for new request
No need for new request
No need for new request
No need for new request

Lets go ahead and modify our test script to run the curl commands in parallel. This simulates multiple incoming request to your node server.

And the output this time???

// serviceHandler.js

As you can see from the output, all request were made in parallel and all ended up calling the auth service.

Wouldn’t it be nice if only one request was made to the auth service for getting the new token while other request wait for token generation to be completed. Once the authentication is completed, it should notify the other requests to use the new token and start working.

Welcome Observer pattern. So this should the workflow should look like

  1. If we have an invalid token, update a variable to represent that we are in the middle of getting new token.
  2. Make an actual request for the new token.
  3. Once the request is completed successfully, unset the variable to show that no request for auth is in progress.
  4. Send an event that new token is available so that other listeners can take appropriate action.

Step 1,2 and 3 are easy. We can maintain a global variable/state in Redis which request can check before making a new request.

Lets implement step 4: Lets start with our Observable code

Now we have to do it listen to done event and we are good. Something like this

Running the same test script would give the below output

// betterServiceHandler
{"newToken":"def"}

As we can see, we only called the token generator service only once!

UPDATE:
As noted by Hoseong Asher Lee, we should use observable.once instead of observable.on as mentioned in the blog. This would make sure an event handler is called only once

Senior Staff Engineer @freshworks. Ex-McKinsey/Microsoft/Slideshare/SAP, Tech Enthusiast, Passionate about India. Opinions are mine

Senior Staff Engineer @freshworks. Ex-McKinsey/Microsoft/Slideshare/SAP, Tech Enthusiast, Passionate about India. Opinions are mine