Laravel passport использует неправильную защиту

#php #laravel #laravel-passport

#php #laravel #laravel-passport

Вопрос:

Я использую Laravel passport для аутентификации по API с «пользователем» поставщика api и «администратором» веб-провайдера. Однако мой URL-адрес для входа в API продолжает использовать поставщика по умолчанию для Интернета вместо своего собственного поставщика.

config/auth.php:

 'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'admin',
        ],

        'api' => [
            'driver' => 'passport',
            'provider' => 'user',
            'hash' => 'false',
        ],
    ],


'providers' => [
        'admin' => [
            'driver' => 'eloquent',
            'model' => AppAdmin::class,
        ],

        'user' => [
           'driver' => 'eloquent',
           'model' => AppModelsUser::class,
         ],
    ],
  

Пользовательская модель:

 <?php

namespace App;

use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;
use LaravelPassportHasApiTokens;

class User extends Authenticatable
{
  
  use AppHttpTraitsUsesUuid, HasApiTokens,Notifiable;
  
  protected $table = 'user';
  protected $primaryKey = 'user_id';

  protected $fillable =
   ['user_id',
   'user_fname',
   'user_lname',
   'user_email',
   'password',
   'user_contact',
   'user_token' ];

   protected $hidden = [
    'password', 'remember_token',
  ];

  protected $casts = [
    'email_verified_at' => 'datetime',
  ];

  public function setPasswordAttribute($password)
  {
      $this->attributes['password'] = bcrypt($password);
  }


}

  

Модель администратора:

 <?php

namespace App;

use IlluminateContractsAuthMustVerifyEmail;
use IlluminateFoundationAuthUser as Authenticatable;
use IlluminateNotificationsNotifiable;

class Admin extends Authenticatable
{
    use Notifiable;

  protected $table = 'admin';
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password',
    ];


    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        'email_verified_at' => 'datetime'
    ];
    
}
  

Контроллер аутентификации API:

 public function login(Request $request){

      $credentials = request(['user_email', 'password']);
      
      if(!auth()->attempt($credentials)){
        return response()->json([
          "message"=>"Invalid credentials"
        ], 201);
      }

      $accessToken = auth()->user()->createToken('authToken')->accessToken;

        return response()->json([
          "message"=>"Login successful",
          "user"=>auth()->user(),
          "access_token"=>$accessToken
        ], 201);

    }
  

Маршрут входа:

 Route::post('/login', 'AuthController@login');
  

Моя ошибка заключается в том, что маршрут входа в систему использует модель администратора по умолчанию вместо модели пользователя, указанной для поставщика API, что выдает мне эту ошибку:

 IlluminateDatabaseQueryException: SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_email' in 'where clause' (SQL: select * from `admin` where `user_email` = user@gmail.com limit 1) 
  

Я видел аналогичную ошибку здесь https://laracasts.com/discuss/channels/laravel/changing-the-model-provider-laravel-passport-authenticates-against и попробовал исправления, предложенные здесь https://github.com/laravel/passport/issues/161#issuecomment-299690583 но они не работают

Комментарии:

1. ваша web защита установлена на 'provider' => 'admin', вот почему

2. Как мне заставить api использовать назначенную ему защиту «user» вместо защиты «admin», назначенной web?

3. я добавил ответ, пожалуйста, взгляните

Ответ №1:

вам нужно создать user защиту, так как вам нужен users session драйвер таблицы для вызова attempt() функции

config/auth.php:

 'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'admin',
    ],
    'user' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'passport',
        'provider' => 'user',
        'hash' => 'false',
    ],
],
  

тогда ваш код должен быть таким

 public function login(Request $request)
{

    $credentials = request(['user_email', 'password']);

    if (!auth()->guard('user')->attempt($credentials)) {
        return response()->json([
            "message" => "Invalid credentials"
        ], 201);
    }

    $accessToken = auth()->guard('user')->user()->createToken('authToken')->accessToken;

    return response()->json([
        "message" => "Login successful",
        "user" => auth()->user(),
        "access_token" => $accessToken
    ], 201);
}
  

ПРИМЕЧАНИЕ: — мы создаем новую защиту, потому что драйвер passport не позволяет использовать attempt() и web охранять установленную вами admin таблицу так