User registration flow in microservices

  softwareengineering

Let’s say I have multiple microservices like authorization service (OAuth2 with JWT), VideoService and MyApplicationService.

The VideoService provides videos for MyApplicationService. Both services save user data.

A frontend makes use of all 3 services and a user doesn’t know that she’s actually using multiple services.

The problem is that the user registers on the authorization service. Therefore, he still needs to be registered at the 2 other services. How should this be done?

The best solution that I’ve come up with so far is registering the user implicitly, so that when an unknown user makes a request, a new user is automatically created (as long as the auth is valid, of course). This seems like a decent solution but doesn’t feel “clean”.

Is there a better, or more standard solution?

This is where a central messaging component works well in a micro services environment. The Authorization service needs to publish an event (send a message to a queue) that a new user was registered, along with the minimal information the other services need. The other services listen for new messages on this queue and respond to the “user registered” message by auto creating their profile.

So basically the workflow should be:

  1. Authentication service publishes a “user registered” message to the user authentication queue

  2. The VideoService and MyApplicationService listen in on the authentication queue, and respond to the “user registered” message

  3. The other two services create the user profile as a result of responding to the “user registered” message.


To be honest, each micro service having its own “user profile” functionality breaks one of the main guidelines of micro service architecture: Each micro service should specialize in 1 and only 1 business function. A “user profile” is a business function.

I recommend extracting the “user profile” functionality of the VideoService and MyApplicationService into yet another service: the User Profile Service.

It would involve identifying a clear abstraction for user profiles in different services. If you can’t reasonably create an abstraction for this concept, then I would keep the user profile in the other services.

1

Based on your question, I would suggest reviewing the following:

  1. “The VideoService provides videos for MyApplicationService”. Ideally, microservices shouldn’t provide (communicate) with each other. They should only serve the user (or external client). Having a network of services talking to each other creates what is called a “distributed big ball of mud”.
  2. “Both services save user data”. This is fine, as long as they save different data. For example, “VideoService” stores the “user preferred video categories”, whether “MyApplicationService” might store the user name and phone number. So each service stores only the “part of the user” that is required for that service to operate (this is the basis to avoid service to service communication).
  3. “he still needs to be registered at the 2 other services”. This is your main question, which I’ll answer below:

If, by “registered” you mean that each service needs to “know” the existence of the user, for example, when a new user is registered, the VideoService creates a record with an empty list of “preferred video categories”, then the right approach would be what Greg Burghardt suggested (I would just clarify that you don’t put a message into a queue, but you publish an event, which ends up being a message to 2 queues, one for each service). You can identify this pattern when you here requirements like “When a user is registered, a default user profile is created” (The “When” part normally identifies a business event that is published and another service is interested in).

If, otherwise, when you say “registered at the 2 other services” you are talking about authentication, then the problem is completely different. I personally wouldn’t have a client talking to multiple apis. Instead I would have a single API gateway which would then call the internal microservices APIs. This gateway would take care of authentication and basic authorization (validate roles or permissions required to access every endpoint). If, on the other hand, you prefer having a client talking directly to all microservices, you should build some shared infrastructure that would take care of single sign on to all APIs, so that the user would have to be registered only once.

5

The point of microservices – or as I call them focussed services – is dealing with one topic on one logial service (which could be several physical instances).

The kind of architecture you describe could be put in the following services:

  • Auth
  • User
  • Application
  • Video
  • (Payment …)

Both services save user data.

From what you write, it is not clear, what “user data” means. If it means something like information correlated to a user identifier, this would be fine. If you are storing some kind of “user”-object, that would be subject to change. Everything user related would be best kept in the User-Service.

As you distribute your application, you distribute your User so to say. Every service has a perspective on what a user is. If you need a summary, you have to aggregate one.


The problem is that the user registers on the authorization service. Therefore, he still needs to be registered at the 2 other services. How should this be done?

It follows an admittedly very simplistic description, but you should get the point:

From what was wirtten above. The job of the auth-Service is simply to build a single point of trust.

The auth service is something like a “box office” offering tickets to enter.

The other services trust valid tickets offered by the auth service.
Their only responsibility is, checking the validity of the ticket the visitor has.

There is no need for the single services to know, whether a specific user exists. They only have to trust the ticket. Or to put it in another way: The user has not to be registered at any other service than the auth service.

The more interesting question would be, how to distribute the information that a basically valid ticket should get invalidated. But that is another topic.

I recommend for further reading:

  • OAuth
  • OAuth introduction

Auth as a Service:

  • Auth0

  • Okta

On Premise

  • Keycloak

TL DR; do the security job at the API Gateway and route the request to microservice if everything is OK.


You should use the API Gateway approach for your microservice architecture.

Let’s say we have an API Gateway (zuul, etc.) You can connect your Auth Server(UAA, keycloak, etc.) directly to that gateway. And define a pre filter that checks the inbound request needs auth. If yes check the token at the gateway level(by asking the Auth Server directly that the token is valid and have a valid authority to do the particular job) and route the request to the microservice that you want to consume.

1

LEAVE A COMMENT