Open behnamazimi opened 6 years ago
Multi Jwt Auth with Laravel and MongoDB
At first, when I faced this problem I asked a question on Stack Overflow, I suggest reading that before continue.
Solution:
After many kinds of research, Here is what I did to add multi auth ability with JWT to my project.
In tymon JWT auth package I changed a file. In JWTAuthServiceProvider
, I changed Tymon\JWTAuth\JWTAuth
and Tymon\JWTAuth\Providers\User\UserInterface
definition type from singleton
to bind
in bootBindings
method.
I defined a new middleware and below code is its handle
method:
public function handle($request, Closure $next){
if (!$request->header('Auth-Type')) {
return response()->json([
'success' => 0,
'result' => 'auth type could not found!'
]);
}
switch ($request->header('Auth-Type')) {
case 'user':
$auth_class = 'App\User';
break;
case 'admin':
$auth_class = 'App\Admin';
break;
case 'provider':
$auth_class = 'App\ServiceProvider';
break;
default:
$auth_class = 'App\User';
}
if (!Helpers::modifyJWTAuthUser($auth_class))
return response()->json([
'status' => 0,
'error' => 'provider not found!'
]);
return $next($request); }
I defined a function with name modifyJWTAuthUser
in my Helpers
and here is its inner:
public static function modifyJWTAuthUser($user_class){
if (!$user_class ||
(
$user_class != 'App\User' &&
$user_class != 'App\Admin' &&
$user_class != 'App\ServiceProvider'
))
return false;
try {
Config::set('jwt.user', $user_class);
Config::set('auth.providers.users.model', $user_class);
app()->make('tymon.jwt.provider.user');
return true;
} catch (\Exception $e) {
return false;
} }
I introduced another $routeMiddleware
like below in Kernel.php
:
... 'modify.jwt.auth.user' => ChangeJWTAuthUser::class
and the last step, Adding 'modify.jwt.auth.user'
middleware to the routes that I want.
But even with this steps, I have encountered a new issue. It was about getting the auth token by credentials in login and getting auth user from the token. (It seems that changing config value not effect on JWTAuth::attempt($credentials)
and $this->auth->authenticate($token)
)
To solve the getting auth user from the token issue:
I created a new middleware CustomGetUserFrom
Token which extends of Tymon's jwt.auth
middleware, I mean GetUserFromToken
and in line 35,
I replaced $user = $this->auth->authenticate($token);
with $user = JWTAuth::toUser($token);
And to solve getting the auth token by credentials in login issue:
At first, I find the auth user and after that, I check the user existence and valid the password with Hash::check()
method, if these conditions return true, I generate a token from the user. Here is my code login:
$admin = Admin::where('email', $request->email)->first();
if (!$admin || !Hash::check($request->get('password'), $admin->password)) {
return response()->json([
'success' => '0',
'error' => 'invalid_credentials'
], 401);
}
I'm not sure about this way but I think it's true until finding a correct way to do!
Conclusion:
Having multi JWT auth ability in Laravel perhaps have many other ways to do but I did like this and shared it to be helpful.
I think the only important point of this issue was app()->make('tymon.jwt.provider.user');
, the ability to remake user provider after config values change.
Any other solutions will be appreciated.
Have you tried this approach link? It seems much more cleaner.
Is this still relevant? If so, what is blocking it? Is there anything you can do to help move it forward?
This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs.
As I explained in my StackOverflow question, I have three authenticatable models and I want JWT to work with each separately.
Even when I change the
jwt.user
andauth.providers.users.model
values manually in config files, it does not effect on my JWT auth.After some deep search in codes, I could not find any method to change default user model before
byCredentials
method ofAuthInterface
that call inJWTAuth::attempt
method.I really don't know what should I do to solve this!