I use...
- Laravel 5.4
- tymon / jwt-auth: 1.0.0-rc.2
I have an application with two authentications. One API is customers , and the other is drivers , each has its own table.
Now let me briefly describe the installation of the JWT package and the updates I made on it.
- I installed the package exactly as described in the JWT .
- Now it's a quick start. Here I updated two
Models , one of them is User and the second Driver . Comes to Configure Auth guard again, I used the configuration for two guards to 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 two Models
Here are User and Driver Routes
Route::group( [ 'prefix' => 'auth', 'middleware' => 'api' ], function () { ....... }); Route::group( [ 'prefix' => 'driver', 'middleware' => 'api' ], function () { ....... });
- Now comes the
AuthController
in the JWT documentation, which is written as construct .
public function __construct() { $this->middleware('auth:api', ['except' => ['login']]); }
I found an article that suggested doing something like this to switch between the two models that we have.
so here it looks with my controller 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 that happens, and the problems that I encountered
Now the api driver works like login only Ex.
localhost:8000/api/driver/login Works fine
but when trying to get a custom id driver like this
localhost:8000/api/driver/me returns an empty array
The second issue.
use login from interface for Ex. http://localhost:8000/login it goes back to the login screen without any errors, because the login information is correct, but defaults in auth.php is 'guard'=>'api' if I change it on 'guard'=>'web' , it logs in correctly.
even User API for Ex. localhost:8000/api/auth/login always return
{ "response": "error", "message": "invalid_email_or_password" }
Update
I decided half way. I updated 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 will look 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 the problem in auth.php here
'defaults' => [ 'guard' => 'driver-api', 'passwords' => 'users', ],
here I need to switch 'guard'=>'api' to 'guard'=>'driver-api' in case the localhost:8000/api/driver/login url is localhost:8000/api/driver/login and 'guard'=>'api' in case if the url request is localhost:8000/api/customer/login any way for 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 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 help, ideas please.