I am developing an application that have a Symfony Messenger component installed to handle async messages. The handler of message need to check some permissions for some particulars users, like if one determinate user should receive an email with information if have edition permissions for example.
To achieve that we use Symfony voters, but when we haven't any user logged into the system like in console commands and async messages is very annoying. What is the best solution to that?
Thank you so much
I would probably prefer to check user's permissions before dispatching a message, but let's think how we can approach if it's not a suitable case.
In order to check user permissions, you need to authenticate a user. But in case you're consuming a message asynchronously or executing a console command it's not straightforward, as you don't have an actual user. However, you can pass user id with your message or to a console command.
Let me share my idea of a simple solution for Symfony Messenger. In the Symfony Messenger, there is a concept of Stamps, which allows you to add metadata to your message. In our case it would be useful to pass a user id with a message, so we can authenticate a user within the message handling process.
Let's create a custom stamp to hold a user id. It's a simple PHP class, so no need to register it as a service.
Now we can add the stamp to a message.
We need to receive and handle the stamp in order to authenticate a user. Symfony Messenger has a concept of Middlewares, so let's create one to handle stamp when we receive a message by a worker. It would check if the message contains the AuthenticationStamp and authenticate a user if the user is not authenticated at the moment.
Let's register it as a service (or autowire) and include into the messenger configuration definition.
That's pretty much it. Now you should be able to use your regular way to check user's permissions, for example, voters.
As for console command, I would go for an authentication service, which would authenticate a user if the user id is passed to a command.