Laravel 5.4:JWT API 在两个表上具有多重身份验证,一个有效,另一个无效
Lravel 5.4: JWT API with multi-auth on two tables one works the other not
我正在使用...
- Laravel 5.4
- tymon/jwt-auth : 1.0.0-rc.2
我有两个身份验证的应用程序 API 一个是 customers
另一个是 drivers
每个都有自己的 table.
现在让我简要描述一下 JWT
包安装和我对它所做的更新。
- 我完全按照 JWT 文档中的描述安装了软件包。
- 现在说到quick start这里我更新了两个
Models
一个是User
和第二个Driver
.
再次来到Configure Auth guard
我用了两个guards
的配置让我展示一下我的快照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,
],
],
现在继续申请 authentication routes
这是我的 Routes
两个 Models
这是 User
和 Driver
路线
Route::group( [
'prefix' => 'auth',
'middleware' => 'api'
], function () {
.......
});
Route::group( [
'prefix' => 'driver',
'middleware' => 'api'
], function () {
.......
});
- 现在
AuthController
在 JWT
文档中 construct
就是这样写的。
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
我发现一些文章建议将其制作成这样,以便在我们拥有的两个模型之间切换。
现在我的控制器看起来像这样。
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
现在驱动程序 api
仅作为 login
工作。
localhost:8000/api/driver/login
工作正常
但是当尝试像这样 id
获取驱动程序用户时
localhost:8000/api/driver/me
它return空array
Second Issue comes.
使用来自 interface
的登录名。 http://localhost:8000/login
它 return 返回登录屏幕没有任何错误,因为登录信息是正确的,但是 auth.php
中的 defaults
是 'guard'=>'api'
如果我更改它'guard'=>'web'
它可以正确登录。
甚至 User API
对于 Ex。 localhost:8000/api/auth/login
总是return
{
"response": "error",
"message": "invalid_email_or_password"
}
更新
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' ] ] );
}
}
并且登录功能是这样的。
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 );
}
但在 auth.php
中仍有问题
'defaults' => [
'guard' => 'driver-api',
'passwords' => 'users',
],
在这里我需要将 'guard'=>'api'
切换为 'guard'=>'driver-api'
如果 URL 请求是 localhost:8000/api/driver/login
和 'guard'=>'api'
如果 URL 请求是 localhost:8000/api/customer/login
任何方式来做到这一点。
更新 2
这里是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 [];
}
}
和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 [];
}
我需要一些帮助,请出主意。
我在 jwt 中使用多重身份验证的示例
我有 2 个模型:
1. 用户
2. 管理员
路线:
Route::post('auth/userlogin', 'ApiController@userLogin');
Route::post('auth/adminlogin', 'ApiController@adminLogin');
控制器:
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',
],
]);
}
}
希望对您有所帮助。
首先让我感谢@AmrAbdelRahman 的努力和时间。
我的问题是应用程序总是使用我的 default authentication "guard"
作为我的默认值
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
所以每次我尝试对另一个用户进行身份验证时,它在默认身份验证期间失败的驱动程序是 api
,在这种情况下它应该使用 driver
。
我在我的案例中所做的是在 boot
下的 App\Providers\AppServiceProvider
中制作一个切换器,这是它的样子
$this->app['router']->matched(function (\Illuminate\Routing\Events\RouteMatched $e) {
$route = $e->route;
if (!array_has($route->getAction(), 'guard')) {
return;
}
$routeGuard = array_get($route->getAction(), 'guard');
$this->app['auth']->resolveUsersUsing(function ($guard = null) use ($routeGuard) {
return $this->app['auth']->guard($routeGuard)->user();
});
$this->app['auth']->setDefaultDriver($routeGuard);
});
现在在我的例子中,如果 $guard =api
它将读取 guard
并正确执行,如果它是 driver
它将使用新的 guard
并按预期执行.希望这对将来有帮助。
无需更改 config/auth.php
中的提供商。
您可以按如下方式更改每个控制器中的 __construct
功能。这样 jwt 就知道要验证哪个模型。
驱动控制器
function __construct()
{
Config::set('jwt.user', Driver::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => Driver::class,
]]);
}
我正在使用...
- Laravel 5.4
- tymon/jwt-auth : 1.0.0-rc.2
我有两个身份验证的应用程序 API 一个是 customers
另一个是 drivers
每个都有自己的 table.
现在让我简要描述一下 JWT
包安装和我对它所做的更新。
- 我完全按照 JWT 文档中的描述安装了软件包。
- 现在说到quick start这里我更新了两个
Models
一个是User
和第二个Driver
. 再次来到
Configure Auth guard
我用了两个guards
的配置让我展示一下我的快照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, ], ],
现在继续申请
authentication routes
这是我的Routes
两个Models
这是 User
和 Driver
路线
Route::group( [
'prefix' => 'auth',
'middleware' => 'api'
], function () {
.......
});
Route::group( [
'prefix' => 'driver',
'middleware' => 'api'
], function () {
.......
});
- 现在
AuthController
在 JWT
文档中 construct
就是这样写的。
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login']]);
}
我发现一些文章建议将其制作成这样,以便在我们拥有的两个模型之间切换。
现在我的控制器看起来像这样。
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
现在驱动程序 api
仅作为 login
工作。
localhost:8000/api/driver/login
工作正常
但是当尝试像这样 id
获取驱动程序用户时
localhost:8000/api/driver/me
它return空array
Second Issue comes.
使用来自 interface
的登录名。 http://localhost:8000/login
它 return 返回登录屏幕没有任何错误,因为登录信息是正确的,但是 auth.php
中的 defaults
是 'guard'=>'api'
如果我更改它'guard'=>'web'
它可以正确登录。
甚至 User API
对于 Ex。 localhost:8000/api/auth/login
总是return
{
"response": "error",
"message": "invalid_email_or_password"
}
更新
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' ] ] );
}
}
并且登录功能是这样的。
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 );
}
但在 auth.php
中仍有问题
'defaults' => [
'guard' => 'driver-api',
'passwords' => 'users',
],
在这里我需要将 'guard'=>'api'
切换为 'guard'=>'driver-api'
如果 URL 请求是 localhost:8000/api/driver/login
和 'guard'=>'api'
如果 URL 请求是 localhost:8000/api/customer/login
任何方式来做到这一点。
更新 2
这里是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 [];
}
}
和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 [];
}
我需要一些帮助,请出主意。
我在 jwt 中使用多重身份验证的示例
我有 2 个模型: 1. 用户 2. 管理员
路线:
Route::post('auth/userlogin', 'ApiController@userLogin');
Route::post('auth/adminlogin', 'ApiController@adminLogin');
控制器:
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',
],
]);
}
}
希望对您有所帮助。
首先让我感谢@AmrAbdelRahman 的努力和时间。
我的问题是应用程序总是使用我的 default authentication "guard"
作为我的默认值
'defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
所以每次我尝试对另一个用户进行身份验证时,它在默认身份验证期间失败的驱动程序是 api
,在这种情况下它应该使用 driver
。
我在我的案例中所做的是在 boot
下的 App\Providers\AppServiceProvider
中制作一个切换器,这是它的样子
$this->app['router']->matched(function (\Illuminate\Routing\Events\RouteMatched $e) {
$route = $e->route;
if (!array_has($route->getAction(), 'guard')) {
return;
}
$routeGuard = array_get($route->getAction(), 'guard');
$this->app['auth']->resolveUsersUsing(function ($guard = null) use ($routeGuard) {
return $this->app['auth']->guard($routeGuard)->user();
});
$this->app['auth']->setDefaultDriver($routeGuard);
});
现在在我的例子中,如果 $guard =api
它将读取 guard
并正确执行,如果它是 driver
它将使用新的 guard
并按预期执行.希望这对将来有帮助。
无需更改 config/auth.php
中的提供商。
您可以按如下方式更改每个控制器中的 __construct
功能。这样 jwt 就知道要验证哪个模型。
驱动控制器
function __construct()
{
Config::set('jwt.user', Driver::class);
Config::set('auth.providers', ['users' => [
'driver' => 'eloquent',
'model' => Driver::class,
]]);
}