如何在Laravel 5.4

时间:2017-07-11 02:34:14

标签: php laravel laravel-5.4

我有一个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,
],

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

  

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

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

  

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

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

有人能让我朝着正确的方向前进吗?

非常感谢你。

4 个答案:

答案 0 :(得分: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')

答案 1 :(得分: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));

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

答案 2 :(得分:0)

可以通过AuthServiceProvider的启动方法中的以下代码来对EloquentUserProvider进行非常小的自定义。

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

  };
});

答案 3 :(得分:0)

如果这对寻求自定义retrieveByCredentials方法的其他人有帮助,则可以在不实现自定义 UserProvider 的情况下进行。 EloquentUserProvider 只需获取一个凭据数组,并使用该数组中每个键/值对的where子句构建一个 User 查询。因此,如果您已经有了定义这些凭据的类,则可以在那里简单地自定义。

就我而言,我有一个实现了 ResetsPasswords ResetPasswordController 。我试图修改提交过程中选择用户的方式(使用ID和密码,而不是电子邮件和密码),所以我覆盖了credentials方法,将 email 替换为像这样的ID_Contact

/**
 * Get the password reset credentials from the request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return array
 */
protected function credentials(Request $request)
{
    return $request->only(
        'password',
        'password_confirmation',
        'token',
        'ID_Contact'
    );
}

ResetsPasswords 实现中,还需要自定义其他位置,以便将我的特定用例付诸实践(加上密码重置表单本身)。采用这种方法时,每种情况都会有所不同。但这可能会为您指明有用的方向,具体取决于您的特定要求。