Franco Franco - 1 month ago 21
Node.js Question

Microservices authentication architecture with passport.js

I'm writting a toy application for practicing microservices and authentication on nodejs (expressjs).

I have a react client, an authentication service and other services (they just respond "Hi" so far).


  • The client will be hosted in a CDN.

  • The auth service listens on port 5000 (for example)

  • The rest of the services listen on port 6000-6100.

  • I have a redis db to store session information (oauth token provided by twitter).

  • A mongodb where the application information is stored (not relevant for this question).



The idea is that an unauthenticated client goes to the auth service by clicking the Twitter button (SSO). Then the auth service obtains the generated twitter oath token and it sets this token in the redis store. Then the token is accessible to the rest of the services so they know if a request is authenticated or not by checking if the it already exists in the redis store (if the user removes its account, it will also be deleted from the redis store).
I send the twitter token back and forth from client to server once authenticated.

enter image description here

I find this approach pretty simple (others use an nginx proxy for authentication but I see no reason for that, except if the services are hosted in different domains, but I don't understand it very well) so I'm worried I'm missing something about security for example.

Questions:


  1. Is this approach correct?

  2. Is it safe to share the twitter token (I think so)?

  3. Is there any security issue I'm not noticing here?


Answer

Using this approach you will have to validate the token in all your services, if you are okay with this then you are probably fine.

The twitter access token may have an expire time that will make it necessary to use a refresh token to get a new access token from the auth service:

  • When the access token expires you would return a 401 to the client, from the Service X that you are trying to talk to.
  • The client would have to call the Auth service providing a refresh token, getting a new access token
    • Finaly the client would be hitting the Service X again with this new access token, have it validated and get the expected response from Service X.

In my recent assignment I wrote a micro-service that proxied all the tokens, using this approach my proxy handled everything from auth to roles and sending 401's for expired tokens and revoking refresh tokens etc. I think this gave me a greater separation of concerns.

Important Note: In the refresh token scenario above my proxy only would experience load for an invalid/expired accesstoken, whilst in your scenario any service could be reached with invalid tokens...

Another approach would be to let Service-A and Service-B call the auth service to validate the tokens, but this would infer a lot of more traffic between the services since each HTTP request with a token has to be validated. In this scenario as well a invalid token request would reach your Service X and hence infer some load on it...