Reputation: 8520
I created a custom Auth driver for my Laravel app. Now I'm wondering what would be the standard way to add additional data to my auth session.
I created a custom guard:
class MyAppGuard extends Guard {
//...
}
A user provider:
class MyAppUserProvider implements UserProviderInterface {
//...
}
I've registered my driver in global.php
:
Auth::extend('mydriver', function($app) {
$provider = new \MyApp\Auth\MyAppUserProvider($app['hash'], 'User');
return new \MyApp\Auth\MyAppGuard($provider, $app['session.store']);
});
Everything seems to work fine, I can call custom methods of MyAppGuard
with Auth::myCustomMethod()
and so on and so forth.
I now want to add all the permissions for the user to the session so that they are accessible over Auth::permissions()
like the user is over Auth::user()
.
How should I do this, I'm sure I could do it in some ugly way but there must be a best practice?
Upvotes: 0
Views: 1679
Reputation: 11119
The existing Guard class gives you all the tools you need for this.
Requesting a relationship on a model caches the relationship, and the logged-in user's model is what's stored in the session data.
Make use of the existing user() function, which checks for a current logged in user or a remember-me cookie, and then stores the session data.
Inside of MyAppGuard:
public function permissions() {
if ($user = $this->user()) {
return $user->permissions;
} else {
return $user;
}
}
There's no need to eager-load the permissions into the user model. Since calling permissions() caches the relationship into the logged-in user model, the data is stored in the session.
You COULD eager-load the permissions by overriding the setUser() function
public function setUser() {
parent::setUser();
$this->user->load('permissions');
}
That would store the permissions into the session data as soon as the user logs in, as opposed to caching the permissions the first time that the permissions() function is called. But, it really makes no difference.
As a sidebar, none of this is technically necessary. If you were to call Auth::user()->permissions at any point in your code, you would cache the current logged in user's credentials in the current session. So an Auth::permissions() function is kind of pointless.
Upvotes: 1
Reputation: 20105
In your provider class do something like:
public function permission()
{
// get the id of the authentication users session
$id = $this->session->get($this->getName());
// now do a query to get the users permission by his/her id
$permission = ...
return $permission;
}
Call it like
Auth::permission();
If you review the code of Laravel Auth. It makes a new user model every time Auth::user();
is called except if it is the same request then they just return the existing data immediately.
The only thing they store in the session is the user id. So I won't suggest using sessions to store your permissions. Just use the existing userid from the session and make a query for the permission then return the data.
From Guard.php
you can access the users identifier like:
$id = $this->session->get($this->getName());
Note: I am not an expert.
Add something like:
protected $permission;
Then set it like
$this->permission = $permission;
This is the same approach laravel is using for Auth::user()
. I don't think it will be slow down you application.
Then in your permission()
function do a check if the $this->permission
is already set.
if (!is_null($this->permission))
{
return $this->permission;
}
// then do the rest here like getting the permission
...
This way if the permission already exist for the request then it returns it rather than doing the whole query again (the part that could make it slow).
Upvotes: 1