Laravel 5.2自定义认证出现错误

7

在为我的laravel 5.2创建自定义认证时,我遇到了错误,然而这段代码在我的laravel 5.1上运行良好。我的config/auth.php文件:

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

    // 'users' => [
    //     'driver' => 'database',
    //     'table' => 'users',
    // ],
],

我的CustomUserProvider.php(Auth / CustomUserProvider)文件

    <?php namespace App\Auth;

use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Hashing\Hasher as HasherContract;
use Illuminate\Contracts\Auth\Authenticatable as UserContract;

class CustomUserProvider implements UserProvider {

    protected $model;

    public function __construct(UserContract $model)
    {
        $this->model = $model;
    }

    public function retrieveById($identifier)
    {

    }

    public function retrieveByToken($identifier, $token)
    {

    }

    public function updateRememberToken(UserContract $user, $token)
    {

    }

    public function retrieveByCredentials(array $credentials)
    {

    }

    public function validateCredentials(UserContract $user, array $credentials)
    {

    }

}

我的CustomAuthProvider.php文件
    <?php namespace App\Providers;

use App\User;
use Auth;
use App\Auth\CustomUserProvider;
use Illuminate\Support\ServiceProvider;

class CustomAuthProvider extends ServiceProvider {

    /**
     * Bootstrap the application services.
     *
     * @return void
     */
    public function boot()
    {
        $this->app['auth']->extend('custom',function()
        {

            return new CustomUserProvider();
        });
    }

    /**
     * Register the application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

}

在Laravel 5.1中,这个功能运行良好,在5.2版本中出现了错误。
InvalidArgumentException in CreatesUserProviders.php line 40:
Authentication user provider [custom] is not defined.

我认为在引导方法中,您必须使用App::provider将自定义用户提供程序注册到应用程序中。您所使用的方式是做同样事情的另一种方式吗? - Alankar More
请在文档中查看更多细节。https://laravel.com/docs/5.2/authentication#adding-custom-user-providers - Alankar More
@AlankarMore 我已经注册了我的服务提供者并自动加载了文件。 - ujwal dhakal
尝试将 'driver' => 'custom' 更改为 'driver' => 'customUser',并将 $this->app['auth']->extend('custom',function() 更改为 $this->app['auth']->extend('customUser',function() - Alankar More
CreatesUserProviders.php文件的第40行抛出InvalidArgumentException异常:未定义身份验证用户提供程序[customUser]。 - ujwal dhakal
4个回答

6
唯一的要点是使用 标签。
$this->app['auth']->provider(... 

代替
$this->app['auth']->extend(...

最后一个应该在5.1中使用,第一个应该在5.2中使用。


2

app/Models/User.php

namespace App\Models;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable {
protected $connection='conn';
protected $table='users-custom';

/**
 * The attributes that are mass assignable.
 *
 * @var array
 */
protected $fillable = [
    'login', 'passwd'
];

/**
 * The attributes excluded from the model's JSON form.
 *
 * @var array
 */
protected $hidden = [
    'passwd',
];

public function getAuthPassword(){
    //your passwor field name
    return $this->passwd;
}

public $timestamps = false;

}

创建 app/Auth/CustomUserProvider.php 文件。
 namespace App\Auth;

use Illuminate\Support\Str;

use Illuminate\Contracts\Auth\Authenticatable as UserContract;
use Illuminate\Contracts\Auth\UserProvider;

/**
 * Description of CustomUserProvider
 *
 */

class CustomUserProvider implements UserProvider {

/**
 * The hasher implementation.
 *
 * @var \Illuminate\Contracts\Hashing\Hasher
 */
protected $hasher;

/**
 * The Eloquent user model.
 *
 * @var string
 */
protected $model;

/**
 * Create a new database user provider.
 *
 * @param  \Illuminate\Contracts\Hashing\Hasher  $hasher
 * @param  string  $model class name of model
 * @return void
 */
public function __construct($model) {
    $this->model = $model;        
}

/**
 * Retrieve a user by their unique identifier.
 *
 * @param  mixed  $identifier
 * @return \Illuminate\Contracts\Auth\Authenticatable|null
 */
public function retrieveById($identifier) {
    return $this->createModel()->newQuery()->find($identifier);
}

/**
 * Retrieve a user by their unique identifier and "remember me" token.
 *
 * @param  mixed  $identifier
 * @param  string  $token
 * @return \Illuminate\Contracts\Auth\Authenticatable|null
 */
public function retrieveByToken($identifier, $token) {
    $model = $this->createModel();

    return $model->newQuery()
                    ->where($model->getAuthIdentifierName(), $identifier)
                    ->where($model->getRememberTokenName(), $token)
                    ->first();
}

/**
 * Update the "remember me" token for the given user in storage.
 *
 * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
 * @param  string  $token
 * @return void
 */
public function updateRememberToken(UserContract $user, $token) {
    $user->setRememberToken($token);

    $user->save();
}

/**
 * Retrieve a user by the given credentials.
 *
 * @param  array  $credentials
 * @return \Illuminate\Contracts\Auth\Authenticatable|null
 */
public function retrieveByCredentials(array $credentials) {
    // First we will add each credential element to the query as a where clause.
    // Then we can execute the query and, if we found a user, return it in a
    // Eloquent User "model" that will be utilized by the Guard instances.
    $query = $this->createModel()->newQuery();

    foreach ($credentials as $key => $value) {            
        if (!Str::contains($key, 'password')) {
            $query->where($key, $value);
        }
    }

    return $query->first();
}

/**
 * Validate a user against the given credentials.
 *
 * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
 * @param  array  $credentials
 * @return bool
     */
    public function validateCredentials(UserContract $user, array $credentials) {
//your method auth
        $plain = $credentials['password'];
        return  md5($plain)==md5($user->getAuthPassword());
    }

/**
 * Create a new instance of the model.
 *
 * @return \Illuminate\Database\Eloquent\Model
 */
public function createModel() {
    $class = '\\' . ltrim($this->model, '\\');
    return new $class;
}

/**
 * Gets the hasher implementation.
 *
 * @return \Illuminate\Contracts\Hashing\Hasher
 */
public function getHasher() {
    return $this->hasher;
}

/**
 * Sets the hasher implementation.
 *
 * @param  \Illuminate\Contracts\Hashing\Hasher  $hasher
 * @return $this
 */
public function setHasher(HasherContract $hasher) {
    $this->hasher = $hasher;

    return $this;
}

/**
 * Gets the name of the Eloquent user model.
 *
 * @return string
 */
public function getModel() {
    return $this->model;
}

/**
 * Sets the name of the Eloquent user model.
 *
 * @param  string  $model
 * @return $this
 */
public function setModel($model) {
    $this->model = $model;

    return $this;
}

}

在config/auth.php文件中

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


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


'users_office' => [
        'driver' => 'customUser',
        'model' => App\Models\User::class,
    ],
// 'users' => [
//     'driver' => 'database',
//     'table' => 'users',
// ],
],

在 \vendor\laravel\framework\src\Illuminate\AuthCreatesUserProviders.php 文件中

 public function createUserProvider($provider)
{
    $config = $this->app['config']['auth.providers.'.$provider];    


    if (isset($this->customProviderCreators[$config['driver']])) {
        return call_user_func(
            $this->customProviderCreators[$config['driver']], $this->app, $config
        );
    }

    switch ($config['driver']) {
        case 'database':
            return $this->createDatabaseProvider($config);
        case 'eloquent':
            return $this->createEloquentProvider($config);
        case 'customUser':
            return $this->createCustomUserProvider($config);
        default:
            throw new InvalidArgumentException("Authentication user provider [{$config['driver']}] is not defined.");
    }
}


protected function createCustomUserProvider($config){        
        return new \App\Auth\CustomUserProvider($config['model']);
    }

添加 App\Providers\CustomUserAuthProvider.php

    namespace App\Providers;

use Auth;
use App\Models\User;
use App\Auth\CustomUserProvider;
use Illuminate\Support\ServiceProvider;

/**
 * Description of CustomAuthProvider
 *
 */

class CustomUserAuthProvider extends ServiceProvider {

/**
 * Bootstrap the application services.
 *
 * @return void
 */
public function boot()
{        
     Auth::extend('customUser', function($app) {
        // Return an instance of Illuminate\Contracts\Auth\UserProvider...
        return new CustomUserProvider(new User);
    });
}

/**
 * Register the application services.
 *
 * @return void
 */
public function register()
{
    //
}

}

1
这是一个解决方案,但它太不干净了。一个可行的解决方案不应该包括对框架本身的更改,特别是供应商文件夹,否则框架就会出问题。在4.2中,可以以一种干净的方式实现,我相信有一种方法可以将自定义创建者注册到“CreatesUserProviders”的$customProviderCreators属性中。 - Cunning

1
将引导功能替换为以下内容:
public function boot()
    {
        Auth::provider('customUser', function($app, array $config) {
            return new CustomUserProvider($config['model']);
        });
    }

1

尝试使用以下方式替换启动函数:

public function boot()
{
    Auth::provider('custom', function($app, array $config) {
        // Return an instance of Illuminate\Contracts\Auth\UserProvider...
        return new CustomUserProvider($app['custom.connection']);
    });
}

我一直在尝试使用 $this->app['auth'],但是不起作用。顺便问一下,custom.connection 在 PHP 中代表什么? - ujwal dhakal
我认为它可能会返回您自定义用户提供程序的连接。因此,无论您使用哪个模型作为自定义用户提供程序驱动程序,该模型实例都将由此custom.connection返回。我不确定需要深入挖掘Laravel API文档。您的UserContract模型是否扩展到User模型? - Alankar More

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接