Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

App client authentication (login) and CQRS

I'm interested in practical scenarios of authentication/login in web application when CQRS pattern is used to build the system.

Say we using HTTP services for commands/queries. And authentication with JWT (or any other authentication token)

  • We send command LogInUser with credentials (HTTP request).
  • Server command handler checks credentials, writes events in the store (if using Event Sourcing).

What then? What should we return as the result of the command? Just ok result with authToken? Then client should query the state in the read service? In this case we just make the whole process longer. And this concern actually refers not only to authentication scenarios but also other scenarios when we send a command and expect to get the result of it execution as soon as possible.

I just would like to hear from people who implemented such things. Want to understand possible practical data/requests flows for authentication using CQRS.

like image 564
WHITECOLOR Avatar asked Nov 21 '17 22:11

WHITECOLOR


1 Answers

Since you are using CQRS, you have decided to separate writing to the application from reading from the application.

  • To write to the application, you use commands.
  • To read from the application, you either wait for events, or you query the read model.

This diagram shows the relation between the different options:

Architecture of a CQRS application

(The diagram is taken from the documentation of wolkenkit, a CQRS and event-sourcing framework for JavaScript and Node.js.)

So, when you send your LogInUser command, the command itself does not return anything (of course, when using HTTP there must be a response, but it should just be a 200 OK, so that you can verify that the server received the command and will care about it sooner or later).

Now the server process the login, verifies the sent credentials, and so on, and generates an appropriate UserLoggedIn event. This event gets stored in the event store, and is then sent to the read model.

The read model does two things with this event:

  • It simply forwards it to the client.
  • It updates any denormalized tables you may have that are interested in this event, so you can query them later.

So your client has two options:

  1. It can wait for the event after having sent the command. Once the event is being received, the client has the JWT.
  2. It can query the read model, until a given record was updated.

As you need to make sure that only the sender of the command is able to receive the JWT, option 1 is actually the only viable way. You can make sure that an event gets only delivered to the client that sent the appropriate command, but you can't have a table that contains all JWTs where people can only read their JWTs before being authenticated. With the read model, you have a chicken-and-egg problem here.

So, to cut a long story short: The client should wait for the appropriate event, and the event contains the JWT. That's it.

like image 87
Golo Roden Avatar answered Oct 22 '22 03:10

Golo Roden