首页 > 解决方案 > 多个身份验证防护无法正常工作

问题描述

我正在尝试为我正在构建的 api 制作多个身份验证保护。两个守卫使用相同的提供者,但使用不同的模型登录。第一个工作正常,但第二个给出了一个奇怪的结果:如果我打印提供者的 userModel,它会打印 SistemaIntegrado 类和 Consultor 类,就好像发出了两个请求一样。

身份验证服务提供者

<?php

namespace App\Providers;

use App\Models\Sapv\Consultor;
use App\Models\SistemaIntegrado;
use App\Services\Auth\JWT\JWTGuard;
use App\Services\Auth\JWT\JWTProvider;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;

class AuthServiceProvider extends ServiceProvider
{
    /**
     * The policy mappings for the application.
     *
     * @var array
     */
    protected $policies = [
        // 'App\Models\Model' => 'App\Policies\ModelPolicy',
    ];

    public function register()
    {
        Auth::provider('integracao', function ($app, array $config) {
            return new JWTProvider($app->make(SistemaIntegrado::class));
        });
        Auth::extend('integracao', function ($app, $name, array $config) {
            return new JWTGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
        });

        Auth::provider('sapvconsultor', function ($app, array $config) {
            return new JWTProvider($app->make(Consultor::class));
        });
        Auth::extend('sapvconsultor', function ($app, $name, array $config) {
            return new JWTGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
        });
    }

    /**
     * Register any authentication / authorization services.
     *
     * @return void
     */
    public function boot()
    {
        $this->registerPolicies();
    }
}

授权文件

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

    'defaults' => [
        'guard' => 'integracao',
//        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'integracao' => [
            'driver' => 'integracao',
            'provider' => 'integracao',
        ],
        'sapvconsultor' => [
            'driver' => 'sapvconsultor',
            'provider' => 'sapvconsultor',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],
        'integracao' => [
             'driver' => 'integracao',
             'model' => \App\Models\SistemaIntegrado::class,
//             'table' => 'users',
        ],
        'sapvconsultor' => [
            'driver' => 'sapvconsultor',
            'model' => \App\Models\Sapv\Consultor::class,
//             'table' => 'users',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
            'throttle' => 60,
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Password Confirmation Timeout
    |--------------------------------------------------------------------------
    |
    | Here you may define the amount of seconds before a password confirmation
    | times out and the user is prompted to re-enter their password via the
    | confirmation screen. By default, the timeout lasts for three hours.
    |
    */

    'password_timeout' => 10800,

];

路线/api.php

<?php

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::permanentRedirect('/', '/v1');
Route::any('/v1', fn() => ['api_version' => '1.0.1']);

Route::prefix('v1')->group(function () {
    Route::middleware(['auth:integracao', 'sapv.connection'])->group(function () {
        Route::prefix('integracao')->group(function () {
            Route::prefix('associado')->group(function () {
                Route::get('/', [\App\Http\Controllers\Integracao\Sapv\AssociadoController::class, 'show']);
                Route::get('boleto', [\App\Http\Controllers\Integracao\Sapv\AssociadoController::class, 'boleto']);
            });
        });
    });

    Route::middleware(['sapv.connection', 'auth:sapvconsultor'])->group(function () {
        Route::prefix('sapvconsultor')->group(function () {
            Route::post('login', [\App\Http\Controllers\Sapv\ConsultorController::class, 'login']);
        });
    });
});

在我的 JWTProvider 中,这是我的 retrieveByCredentials 函数

public function retrieveByCredentials(array $credentials): ?Model
    {
        try {
            $token = JWTParser::parseToken($credentials['token']);
            $user = $this->userModel->newQuery()->find($token->claims->get('sub'));
            var_dump($this->userModel::class);
            
            return $user;
        } catch (\Exception $e) {
            return null;
        }
    }

当我尝试到达路线 /v1/sapvconsultor/login 我得到这个输出

string(27) "App\Models\SistemaIntegrado"
string(25) "App\Models\Sapv\Consultor"
{"message":"Unauthenticated."}

如果我转到路线 /v1/integracao/associado/boleto 这是输出

string(27) "App\Models\SistemaIntegrado"

我不知道我做错了什么,请有人可以建议吗?

标签: phplaravellaravel-authentication

解决方案


推荐阅读