php - 拉维尔 5.4 : JWT API with multi-auth on two tables one works the other not

标签 php laravel authentication jwt laravel-5.4

我正在使用...

  • 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

这是 UserDriver路线

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']]);
    }

我发现一些文章建议将它变成这样,以便在我们拥有的两个模型之间切换。

现在我的 Controller 看起来像这样。

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它返回空 array

Second Issue comes.

使用来自 interface 的登录对于前。 http://localhost:8000/login它没有任何错误地返回到登录屏幕,因为登录信息是正确的,但是 defaultsauth.php'guard'=>'api'如果我将其更改为 'guard'=>'web'它可以正确登录。

即使是User API对于前。 localhost:8000/api/auth/login总是回来

{
    "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 [];
        }

我需要一些帮助,请出主意。

最佳答案

无需更改 config/auth.php 中的提供程序。

您可以按如下方式更改每个 Controller 中的 __construct 函数。这样 jwt 就知道要验证哪个模型。

驱动 Controller

function __construct()
{
    Config::set('jwt.user', Driver::class);
    Config::set('auth.providers', ['users' => [
            'driver' => 'eloquent',
            'model' => Driver::class,
        ]]);
}

关于php - 拉维尔 5.4 : JWT API with multi-auth on two tables one works the other not,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49212086/

相关文章:

php - 如何从MySQL表中的特定列获取值,然后将其显示在新页面上

php - 使用 PHP (Codeigniter) 将标签 html 插入 MYSQL

laravel - Azure 语音到文本 Webhook header X-MicrosoftSpeechServices-Signature 算法?

mysql - Laravel 抛出一般错误 : 1215 Cannot add foreign key constraint"when I create foreign keys

php - Laravel Envoyer 存储同步

asp.net - 登录控件 : WebForms UnobtrusiveValidationMode requires a ScriptResourceMapping for 'jquery' . 添加名为 jquery 的 ScriptResourceMapping

php - 在文本框中输入时不显示自动完成功能,但值显示在控制台中

使用 IP 作为主机时,PHP 无法连接到 MySQL Workbench,但使用 localhost 时工作正常

ios - 将p12导入keychain时要选择什么

servlets - 当用户未登录时,Servlet 过滤器在无限重定向循环中运行