如何在Laravel 5.4中添加自定义用户提供程序

问题描述 投票:5回答:3

我有一个Laravel 5.4应用程序,其中我必须从外部API验证我的管理员用户,当成功登录时,它返回带有用户信息的JSON。

我正在创建一个自定义守卫来做到这一点:

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

        'custom' => [
            'driver' => 'session',
            'provider' => 'customusers'
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],

这是我的自定义提供者:

'providers' => [
    'users' => [
        'driver' => 'eloquent',
        'model' => App\User::class,
    ],

    'customusers' => [
        'driver' => 'jsonresponse',
        'model' => App\Admin::class,
    ]
],

在那之后,我不知道如何继续。我已经阅读了一些像the one from George Buckingham这样的教程,并且我创建了一个自定义用户提供程序(现在我只需要它从EloquentUserProvider扩展,最终我将覆盖一些函数来连接到API)

<?php

namespace App\Providers;

use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Support\Str;

class CustomUserProvider extends EloquentUserProvider { 

}

然后在App \ Providers \ AuthServiceProvider中注册它

public function boot()
{
    $this->registerPolicies();

    Auth::provider('jsonresponse', function($app, array $config) {
        return new CustomUserProvider($app['hash'], $config['model']);
    });
}

并在config / app.php中

'providers' => [

    // Lots of other providers

    // Own providers
    App\Providers\CustomUserProvider::class,
],

但在那之后,我收到以下错误:

传递给Illuminate \ Auth \ EloquentUserProvider :: __ construct()的参数1必须是Illuminate \ Contracts \ Hashing \ Hasher的实例,给出Illuminate \ Foundation \ Application的实例,在/ var / www / public / iberorides / vendor / laravel中调用第612行的/framework/src/Illuminate/Foundation/Application.php并定义

如果我覆盖我的CustomUserProvider的构造函数并更改AuthServiceProvider中的闭包中的params,我会收到以下错误:

传递给Illuminate \ Foundation \ Application :: bootProvider()的参数1必须是Illuminate \ Support \ ServiceProvider的实例,App / Providers \ IberoUserProvider的实例,在/ var / www / public / iberorides / vendor / laravel / framework中调用/src/Illuminate/Foundation/Application.php在第771行并定义

这让我觉得我没有以正确的方式做事。

有人能把我放在正确的方向吗?

非常感谢。

php laravel laravel-5.4
3个回答
4
投票

解决方案很简单。

首先,尽管其他教程说,你不必在配置提供程序中注册CustomUserProvider(这里是Laravel 5.4)。这是我得到的错误的原因。

我只需要覆盖EloquentUserProviderretrieveByCredentials(array $credentials)中的两个方法,你可以根据提供的凭据返回一个模型,validateCredentials(UserContract $user, array $credentials)返回一个布尔值,具体取决于轮询凭据是否正确。

您可以将此自定义提供程序类与许多提供程序一起使用,而不仅仅是一个

'providers' => [
    'customusers' => [
        'driver' => 'jsonresponse',
        'model' => App\User::class,
    ],

    'customadmins' => [
        'driver' => 'jsonresponse',
        'model' => App\Admin::class,
    ],
],

之后,当您需要与任何提供商检查身份验证时,您需要提供提供者作为保护,例如Auth::guard('customusers')


2
投票

我找到的所有解决方案都不适合我,所以我想出了一个非常简单的方法。 (Laravel 5.4)

我的问题是我必须允许用户使用他们的电话号码登录。

我重写EloquentUserProvider

class PhoneUserProvider extends EloquentUserProvider
{
    public function retrieveByCredentials(array $credentials)
    {
        if (!$credentials) {
            return null;
        }

        // Fallback to original email authorization
        if (filter_var($credentials['email'], FILTER_VALIDATE_EMAIL)) {
            return parent::retrieveByCredentials($credentials);
        }

        // Assume we are logging in with a phone number
        return UserModel::where('phone', $credentials['email'])->first();
    }
}

在我的AppServiceProvider启动方法中,我添加了以下行:

Auth::setProvider(new PhoneUserProvider(app(Hasher::class), UserModel::class));

您甚至可以根据某些条件在登录控制器中设置提供程序等。


0
投票

可以通过AuthServiceProvider的引导方法中的以下代码完成EloquentUserProvider的非常小的自定义。

Auth::provider('eloquent', function($app, array $config)
{
  return new class($app['hash'], $config['model']) extends \Illuminate\Auth\EloquentUserProvider
  {

  };
});
© www.soinside.com 2019 - 2024. All rights reserved.