Lravel 5.4:在两个表上具有多重身份验证的JWT API,一个起作用,另一个不起作用 [英] Lravel 5.4: JWT API with multi-auth on two tables one works the other not

查看:77
本文介绍了Lravel 5.4:在两个表上具有多重身份验证的JWT API,一个起作用,另一个不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用...

  • Laravel 5.4
  • tymon/jwt-auth:1.0.0-rc.2

我有两个身份验证API的应用程序,一个是customers,另一个是drivers,每个都有自己的表.

I have application with two authentications API one is customers and the other is drivers each one has it's own table.

现在让我简要介绍一下JWT软件包的安装以及我对此所做的更新.

now let me describe shortly JWT package installation and the updates I did on it.

  • 我按照 JWT 文档中所述安装了软件包完全是
  • 现在进入快速开始,这里我更新了两个Models一个是User,另一个是Driver.
  • 再次来到Configure Auth guard,我使用了两个guards的配置,让我展示了auth.php的快照.

  • I installed the package as described in the JWT documents exactly.
  • Now comes to the quick start here I updated two 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,
        ],
    ],

  • 现在继续使用authentication routes进行应用,这是我的Routes用于两个Models

  • Now continue the application with authentication routes here is my Routes for the two Models

    这是UserDriver路线

    Route::group( [
        'prefix'     => 'auth',
        'middleware' => 'api'
    ], function () {
        .......
    });
    
    Route::group( [
        'prefix'     => 'driver',
        'middleware' => 'api'
    ], function () {
       .......
    });
    

    • 现在是AuthController
      • Now comes the AuthController
      • construct就是这样写的.

        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

        现在,驱动程序api仅作为login工作.

        Now the driver api is working as login only Ex.

        localhost:8000/api/driver/login正常

        但是当尝试像这样获得驱动程序用户id

        but when try to get the driver user id like this

        localhost:8000/api/driver/me它返回空array

        第二个问题来了.

        Second Issue comes.

        interface中用于Ex的使用登录. http://localhost:8000/login它会返回登录屏幕而没有任何错误,因为登录信息正确,但是auth.php中的defaults'guard'=>'api',如果我将其更改为'guard'=>'web'则可以正确登录.

        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.

        甚至是User API. localhost:8000/api/auth/login始终返回

        {
            "response": "error",
            "message": "invalid_email_or_password"
        }
        

        更新

        我解决了一半 我将AuthController更新为类似这样的内容.

        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',
            ], 
        

        如果URL请求为localhost:8000/api/driver/login,则我需要将'guard'=>'api'切换为'guard'=>'driver-api';如果URL请求为localhost:8000/api/customer/login,则需要将'guard'=>'api'切换为'guard'=>'api'.

        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.

        更新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 [];
                }
        

        我需要一些帮助,请给我一些想法.

        I need some help, Ideas please.

        推荐答案

        首先,我感谢您@AmrAbdelRahman所做的努力和时间.

        First let me thank you @AmrAbdelRahman for you efforts and your time.

        我的问题是应用程序总是使用我的default authentication "guard",因为我的默认外观是这样的

        My problem was the application always using my default authentication "guard" as my default looks like that

        'defaults' => [
                'guard'     => 'api',
                'passwords' => 'users',
            ],
        

        因此,每次我尝试对另一个用户进行驱动程序身份验证时,在默认身份验证期间失败的驱动程序均为api,在这种情况下,应使用driver.

        so every time I try to authenticate the other user which was the driver it fails during the default authenticate is api and the it should using driver in this case.

        在我的情况下,我要做的是在boot下的App\Providers\AppServiceProvider中制作一个切换器,这是这样的样子

        what I did in my case was making a switcher in my App\Providers\AppServiceProvider under the boot here is how it looks like

        $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并按预期进行操作.希望这会在将来对您有所帮助.

        Now in my case if the $guard =api it will read that guard and act correctly and if it's driver it will use the new guard and act as expected. Hope this will help some one in future.

        这篇关于Lravel 5.4:在两个表上具有多重身份验证的JWT API,一个起作用,另一个不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆