8

I'm learning how to design a Microservice architecture. For example, here is a simple Microservice architecture:

enter image description here

I'm kind of confused by the Account Service.

As we know, for a web service, normally we need to perform a login first, and then we can get access to some services. For example, we perform a login, and then we can post a blog or buy some products. As shown from the above image, services such as "post a blog", "buy some products" should be independent of each other, because this is how a micro service works. But for these services, we must perform a login, which means that when a client sends a request to some service, the service must check the authorization of the client. To my understanding, this will cause many duplicated code.

Let's say I login a web server, and its Account Service sends back a token to me. Then I write a blog and send it to the Blog Service. When the Blog Service receives my request, it will first validate the token. After that, I buy some products, so I send a request to the relative service. Again, this service will validate the token too. Besides, to validate a token, the server has to store some data too, right?

So does Microservice architecture mean that I have to design a database in which all services has access to store the data used to validate a user-token? And does Microservice architecture mean that we have to duplicate some code on each service to validate the token?

10

When developing and deploying actual micro services, you do not want your consumer to access the microservices directly for several (main) reasons:

  • it introduces heavy coupling on the client to your internal representation, to a certain degree this is similar to a case where you would expose a database directly,
  • it complicates integration on the consumer side, because they need to remember where each service lives, on which URL,
  • it is difficult to perform global checks and filters, such as API throttling,...

You have encountered one of those problems, which will certainly lead to others in the future.

Microservices should be internal in general. They may talk to each other in a synchronous (request/response) manner, although asynchronous (through events) communication is preferred, which makes it easier to deploy microservices separately, and also leads to more proper microservice design regarding their separation. With publicly accessible microservices, if you need to expose them to the outside world, put an API Gateway in front of them.

API Gateway acts yet as another system, through which flow all requests. It's usually pretty light weight and responsible for routing of requests to appropriate internal microservices. But it has one great added benefit. You can put necessary global operations in it (since it's your entry point). This includes authentication (who a user is) and optionally authorisation (is the user permitted to).

Since the API gateway authenticates your user (or otherwise rejects the request as a failed auth) and then forwards the request further to an internal microservice, the microservices themselves do not need to bother with authentication anymore. It's guaranteed to be performed before they're called, and they can trust the id of the user in the request. For most calls the id is the only thing necessary (without any additional checks), therefore in such context the operations needs not to bother with user logic at all.

With authorisation, it's a little bit different and depends on the context. If there are simple rules such as: "This endpoint may be called only by users with the role admin," then such rule can probably be placed in the API Gateway, to reject the request before even routing it into the microservice, which would reject it anyway. With more complicated authorisation closer to the business rules, it's necessary that the given microservice keeps their copy of a user and checks against its database by itself (circumventing the synchronous like communication).

API Gateway provides also another benefit for your ecosystem. You can introduce multiple backends for your internal microservices, e.g. one for e-commerce, one for some mobile application,... thanks to which the consumer worries only about the exposed endpoints and is not overwhelmed by logic which needs to be internally available in your system but is only consumed from different contexts (therefore exposed as a different backend).

Why is synchronous communication frowned upon? It's an easy mechanism how to obtain data among microservices, but it leads to direct coupling, because of which you need to introduce patterns like Circuit breakers, and starts to introduce single points of failure in your system, where a single failing microservice (on which tons of other microservices depend) may collapse your entire system. Event-driven systems are more resilient to this type of failure.

8
  • 1
    Why add a single point of failure to your system? DNS and a load balancer will provide the same benefits with less complexity.
    – Telastyn
    Jan 11 at 15:37
  • I would encourage anyone who finds this answer compelling to open the inspector on their browser and look at the network view. It think you'll find that 'real' microservices do in fact get accessed directly quite often. I personally think the API Gateway pattern is one of the most overused (if not inherently flawed) patterns to come about in recent times. I won't claim it has no legitimate use but I think it's become a security blanket for those who have not really become comfortable with microservices and core REST principles.
    – JimmyJames
    Jan 11 at 18:55
  • @Telastyn, API gateway is an extremely thin system, with no transactional requirement, it's extremely easy to scale out. Since you mention a load balancer to circumvent the single point of failure, how exactly does a load balancer prevent this? It can lead to exactly the same problem. Regarding your answer, you mention that pretty much all services depend on the user service. Your suggestion leads to a single point of failure too.
    – Andy
    Jan 11 at 19:07
  • 2
    @JimmyJames, in my experience, authentication is probably the last of advantages (where I don't mean authentication in the terms of logging in a user, but instead a verification that the authentication token may be trusted). The main advantages are common place to protect your services from (D)DoS attacks, throttling, introduction of backends for frontends, simpler API discovery. I have used the API Gateway for a few projects now, and I have yet to come to any limitation. I don't believe large companies such as Uber or Netflix would use the pattern if it was "inherently flawed".
    – Andy
    Jan 11 at 19:47
  • 1
    @JimmyJames, it is much easier to configure something like WAF on Cloudfare in front of the API gateway, instead of doing it for each exposed microservices.
    – Andy
    Jan 12 at 5:34
6

Besides, to validate a token, the server has to store some data too, right?

It will likely log the attempt, but it won't store any extra data per validation.

So does micro service architecture mean that I have to design a database that all of services can access to store the data that used to validate a user-token?

Not a database. You'll likely just need the public key to assert that the token was properly signed by the Account Service.

And does micro service architecture mean that we have to duplicate some codes on each service to validate the token?

I prefer a shared library to simplify things, but yes, your Account/User service tends to be a shared dependency for most if not all of your other microservices.

2
  • You'll likely just need the PUBLIC key. The private key should never leave the Account Service. Unless you are doing a simple MAC, but the again it is not called a private key but a shared secret.
    – D. Kovács
    Jan 11 at 10:10
  • @D.Kovács - ah yes, you’re right. Dangers of posting late at night. Editing.
    – Telastyn
    Jan 11 at 15:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.