I am using...
I have application with two authentications API one is customers
and the other is drivers
each one has it's own table.
now let me describe shortly JWT
package installation and the updates I did on it.
Models
one is the User
and the second Driver
.Comes here to the Configure Auth guard
again I used the configuration for the two guards
let me show a snapshot of my auth.php
.
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
'driver' => [
'driver' => 'session',
'provider' => 'drivers',
],
'driver-api' => [
'driver' => 'jwt',
'provider' => 'drivers',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
'drivers' => [
'driver' => 'eloquent',
'model' => App\Models\Driver::class,
],
],
Now continue the application with authentication routes
here is my Routes
for the two Models
Here is the User
and Driver
Routes
Route::group( [
'prefix' => 'auth',
'middleware' => 'api'
], function () {
.......
});
Route::group( [
'prefix' => 'driver',
'middleware' => 'api'
], function () {
.......
});
AuthController
in the JWT
documentation the construct
is writing like that.
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
I found some article that suggest to make it something like this to switch between the two models we have.
so here with my controller looks like now.
public function __construct() {
$this->user = new User;
$this->driver = new Driver;
}
public function userLogin( Request $request ) {
Config::set( 'jwt.user', 'App\Models\User' );
Config::set( 'auth.providers.users.model', User::class );
$credentials = $request->only( 'email', 'password' );
$token = null;
try {
if ( $token = $this->guard()->attempt( $credentials ) ) {
return response()->json( [
'response' => 'error',
'message' => 'invalid_email_or_password',
] );
}
} catch ( JWTAuthException $e ) {
return response()->json( [
'response' => 'error',
'message' => 'failed_to_create_token',
] );
}
return response()->json( [
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am front user',
],
] );
}
public function driverLogin( Request $request ) {
Config::set( 'jwt.user', 'App\Models\Driver' );
Config::set( 'auth.providers.users.model', Driver::class );
$credentials = $request->only( 'email', 'password' );
$token = null;
try {
if ( ! $token = $this->guard()->attempt( $credentials ) ) {
return response()->json( [
'response' => 'error',
'message' => 'invalid_email_or_password',
] );
}
} catch ( JWTAuthException $e ) {
return response()->json( [
'response' => 'error',
'message' => 'failed_to_create_token',
] );
}
return response()->json( [
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am driver user',
],
] );
}
public function me() {
return response()->json( $this->guard()->user() );
}
public function logout() {
$this->guard()->logout();
return response()->json( [ 'message' => 'Successfully logged out' ] );
}
public function refresh() {
return $this->respondWithToken( $this->guard()->refresh() );
}
protected function respondWithToken( $token ) {
return response()->json( [
'access_token' => $token,
'token_type' => 'bearer',
'expires_in' => $this->guard()->factory()->getTTL() * 60
] );
}
public function guard() {
return Auth::guard();
}
Now with is happening and the problems I faced
Now the driver api
is working as login
only Ex.
localhost:8000/api/driver/login
Working fine
but when try to get the driver user id
like this
localhost:8000/api/driver/me
it return empty array
Second Issue comes.
the use login from the interface
for Ex. http://localhost:8000/login
it returns back to the login screen without any errors becouse the login information is right but the defaults
in the auth.php
is 'guard'=>'api'
if I change it to 'guard'=>'web'
it do the login correctly.
even the User API
for Ex. localhost:8000/api/auth/login
always return
{
"response": "error",
"message": "invalid_email_or_password"
}
Update
I solved half the way I updated the
AuthController
to be something like this.
public function __construct() {
if ( Request()->url() == '/api/driver/me' ) {
$this->middleware( 'auth:driver-api', [ 'except' => [ 'login' ] ] );
} elseif ( Request()->url() == '/api/customer/me' ) {
$this->middleware( 'auth:api', [ 'except' => [ 'login' ] ] );
}
}
and the login function to be something like this.
public function login() {
if ( Request()->url() == '/api/driver' ) {
Config::set( 'auth.providers.users.model', Driver::class );
$credentials = request( [ 'email', 'password' ] );
if ( ! $token = auth()->attempt( $credentials ) ) {
return response()->json( [ 'error' => 'Unauthorized' ], 401 );
}
return $this->respondWithToken( $token );
}
Config::set( 'auth.providers.users.model', User::class );
$credentials = request( [ 'email', 'password' ] );
if ( ! $token = auth()->attempt( $credentials ) ) {
return response()->json( [ 'error' => 'Unauthorized' ], 401 );
}
return $this->respondWithToken( $token );
}
but still have problem in auth.php
here it is
'defaults' => [
'guard' => 'driver-api',
'passwords' => 'users',
],
here I need to switch the 'guard'=>'api'
to be 'guard'=>'driver-api'
in case if URL request is localhost:8000/api/driver/login
and 'guard'=>'api'
in case if URL request is localhost:8000/api/customer/login
any way to do this.
Update 2
Here is the driver
Model
use Tymon\JWTAuth\Contracts\JWTSubject;
use Illuminate\Foundation\Auth\User as Authenticatable;
class Driver extends Authenticatable implements JWTSubject {
protected $guard = 'driver';
protected $fillable = [
...
'email',
'password',
...
];
protected $hidden = [
'password',
'remember_token',
];
public function getJWTIdentifier() {
return $this->getKey();
}
public function getJWTCustomClaims() {
return [];
}
}
and the User
Model
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class User extends Authenticatable implements JWTSubject {
use Notifiable;
protected $fillable = [
'name',
'email',
'password',
];
protected $hidden = [
'password',
'remember_token',
];
public function getJWTIdentifier() {
return $this->getKey();
}
public function getJWTCustomClaims() {
return [];
}
I need some help, Ideas please.
There is no need to change the providers in config/auth.php
.
You can change the __construct
function in each of your controllers as follows. So that jwt know which model to authenticate.
DriverController
function __construct()
{
Config::set('jwt.user', Driver::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => Driver::class,
]]);
}
My example when i used multi auth with jwt
I have 2 models : 1. users 2. admins
the routes :
Route::post('auth/userlogin', 'ApiController@userLogin');
Route::post('auth/adminlogin', 'ApiController@adminLogin');
the controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Http\Requests;
use Config;
use JWTAuth;
use JWTAuthException;
use App\User;
use App\Admin;
class ApiController extends Controller
{
public function __construct()
{
$this->user = new User;
$this->admin = new Admin;
}
public function userLogin(Request $request){
Config::set('jwt.user', 'App\User');
Config::set('auth.providers.users.model', \App\User::class);
$credentials = $request->only('email', 'password');
$token = null;
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json([
'response' => 'error',
'message' => 'invalid_email_or_password',
]);
}
} catch (JWTAuthException $e) {
return response()->json([
'response' => 'error',
'message' => 'failed_to_create_token',
]);
}
return response()->json([
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am front user',
],
]);
}
public function adminLogin(Request $request){
Config::set('jwt.user', 'App\Admin');
Config::set('auth.providers.users.model', \App\Admin::class);
$credentials = $request->only('email', 'password');
$token = null;
try {
if (!$token = JWTAuth::attempt($credentials)) {
return response()->json([
'response' => 'error',
'message' => 'invalid_email_or_password',
]);
}
} catch (JWTAuthException $e) {
return response()->json([
'response' => 'error',
'message' => 'failed_to_create_token',
]);
}
return response()->json([
'response' => 'success',
'result' => [
'token' => $token,
'message' => 'I am Admin user',
],
]);
}
}
I hope that's help you .
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With