Best way to add more user information in UserInterface?

Hi,

I continue my good progress in my project (API with OAuth2 + RBAC) and have another question… :wink:
Now my OAuth2 service working, and i can also retrieve the UserInterface::class in my action provided by zend-expressive-authentication.

....
$user = $request->getAttribute(UserInterface::class, false);
...

If by example my oauth2 user is an email, i’ll have this email in $user->getIdentity().

But i need to retrieve the user_id (numeric or uuid) in my database that correspond with this email in another table like “user” (where have id, email, firstname, lastname, zip, city, … ). With that user_id i’ll can add it in my model request like that: (example: to get only customers managed by this authenticated user)

$customers = $this->customerTable->fetchAllByUserId($userId);
...
  • Is it better to create a new middleware that are between authentication and authorization for that? Don’t know if is possible…
  • Or is it possible to fill directly the UserInterface in authentication with more data?
  • Or just add some logic and model request in each action to get the user_id that correspond to the identity provided by the UserInterface?

Thanks for your advice!

zend-expressive-authentication-user

If you authenticate a user by email, you don’t need to use that as the identity. You can store the user id in your session instead.

Thanks @xtreamwayz for your answer but in my case i use OAuth2.

I’m login with my email and password (oauth_users table) and i got a valid JWT token. II add this token to all my next API requests and i can retreive the UserInterface identity (email) in my action (work).

The user_id is not in the OAuth2 table but in another one that i created “user” (user_id, email, …). When i create a new user, i create in oauth_users AND my own “user” table (i guess it is the good way).

I have to link the email from identity to my email user table and get the user_id…

My question was is it a way to do that directly in a special mddleware or modify the UserInterface data before or just do it in each of my action?

I’m looking into this myself as well. I’ve tried other ways, but they all ended up copying all related classes from all packages and modify them.

Right now I’m thinking about adding another middleware that will check if the UserInterface object in the request is just the interface or an actual fully loaded User object. If it is not an instance of the User class, it will get the user from the repository and inject it as the UserInterface::class.

I also thought about something like you but didn’t know if was a good solution. I will test it!
Let me know if you found a better idea… Thanks!

@MichaelB and @xtreamwayz this is actually a limit of zend-expressive-authentication, it builds only UserInterface instance using a UserTrait.
We should improve this allowing the usage of any UserInterface implementation. I’ll work on a proposal for this. Thanks for sharing your use case.

@enrico Actually, it’s not a real problem anymore for me. On the pages that I need it, I load the full user object and override it with a typehint for my IDE. I load / inject the user in a middleware where needed or inside the action class:

        $user = $request->getAttribute(UserInterface::class);
        if (! $user instanceof User) {
            $user = $this->userRepository->find($user->getIdentity());
        }

The advantage of this is that a user is only fully loaded where needed. And most of the time the id, a username and it’s roles are more then enough. But if you find a better solution that would be welcome.