【问题标题】:Laravel passport uses wrong guardLaravel 护照使用了错误的防护
【发布时间】:2021-02-05 08:18:32
【问题描述】:

我使用 Laravel 护照进行 API 身份验证,API 提供者“用户”和网络提供者“管理员”。但是,我的 API 登录 URL 一直使用 web 的默认提供程序,而不是它自己的提供程序。

配置/auth.php:

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

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


'providers' => [
        'admin' => [
            'driver' => 'eloquent',
            'model' => App\Admin::class,
        ],

        'user' => [
           'driver' => 'eloquent',
           'model' => App\Models\User::class,
         ],
    ],

用户模型:

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
use Laravel\Passport\HasApiTokens;

class User extends Authenticatable
{
  
  use \App\Http\Traits\UsesUuid, 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 Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;

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

我的错误是登录路由使用默认的 Admin 模型而不是为 API 提供者指定的 User 模型给我这个错误:

Illuminate\Database\QueryException: 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 但它们不起作用

【问题讨论】:

  • 你的 web 保护设置为 'provider' =&gt; 'admin', 这就是原因
  • 如何让 api 使用分配给它的 'user' 保护而不是分配给 web 的 'admin' 保护?
  • 我已经添加了答案请看一下

标签: php laravel laravel-passport


【解决方案1】:

您需要创建一个user 守卫,因为您需要userssession 驱动程序来调用attempt() 函数

配置/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);
}

注意:- 我们创建了新的守卫,因为护照驱动程序不允许使用 attempt()web 守卫你已经设置了 admin 表所以

【讨论】:

    猜你喜欢
    • 2018-09-26
    • 1970-01-01
    • 1970-01-01
    • 2018-02-19
    • 2017-07-27
    • 2018-05-15
    • 1970-01-01
    • 2018-01-19
    • 2018-12-20
    相关资源
    最近更新 更多