问题
I have to user models in my eloquent:
- User
- OfficeUser
OfficeUser is in defined in the JWT config as standard model. Now I have written a Middleware for authenticate each of them
authUser:
public function handle($request, Closure $next)
{
Config::set('auth.providers.users.model', \App\User::class);
try {
if (! $user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent'], $e->getStatusCode());
}
return $next($request);
}
authOfficeUser
public function handle($request, Closure $next)
{
try {
if (! $user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent'], $e->getStatusCode());
}
return $next($request);
}
Additionally I have a login function for each of them:
LoginUser
if ($user){
if (Hash::check($request->password, $user->password)) {
// grab credentials from the request
$credentials = $request->only('email', 'password');
try {
// attempt to verify the credentials and create a token for the user
Config::set('auth.providers.users.model', \App\User::class);
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// something went wrong whilst attempting to encode the token
return response()->json(['error' => 'could_not_create_token'], 500);
}
LoginOfficeUser
if ($user){
if (Hash::check($request->password, $user->password)) {
// grab credentials from the request
$credentials = $request->only('email', 'password');
try {
// attempt to verify the credentials and create a token for the user
Config::set('auth.providers.users.model', \App\OfficeUser::class);
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// something went wrong whilst attempting to encode the token
return response()->json(['error' => 'could_not_create_token'], 500);
}
Unfortunately when I login and try to call a route behind the authUser Middleware I get an "user_not_found"
Does anybody have an idea why this happens? OfficeUser authentication works fine
回答1:
Posting for anyone who finds this questions
Although it's not recommended to have two user tables, but I had a similar requirement of setting up JWT with one of our clients. This is how I solved the issue.
No need to make any changes to the providers in `config/auth.php'
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
]
In your authentication controller, dynamically modify the model used by the providers by setting
\Config::set('auth.providers.users.model', \App\Trainer::class);
Example code
In authenticate() method
if ($credentials['user_type'] == 'consultant') {
\Config::set('auth.providers.users.model', \App\Trainer::class);
} else {
\Config::set('auth.providers.users.model', \App\User::class);
}
//Find the user
//Create the token
if ($user) {
$customClaims = ['user_type' => $credentials['user_type']];
$token = JWTAuth::fromUser($user,$customClaims);
} else {
return response()->json(['error' => 'invalid_credentials'], 401);
}
You will have to do the same while parsing the token to authenticate the user as well. Example code
In getAuthenticatedUser() method
$payload = JWTAuth::parseToken()->getPayload();
$user_type = $payload->get('user_type');
if($user_type === 'consultant'){
\Config::set('auth.providers.users.model', \App\Trainer::class);
}else{
\Config::set('auth.providers.users.model', \App\User::class);
}
if (!$user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
回答2:
You can change the __construct
function in each of your controllers as follows. So that jwt know which model to authenticate.
OfficeUserController
function __construct()
{
Config::set('jwt.user', OfficeUser::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => OfficeUser::class,
]]);
}
来源:https://stackoverflow.com/questions/36839158/multiple-user-models-laravel-jwt-auth