自定义用户提供者可集成非Eloquent模型与多种数据源,如NoSQL、API、LDAP或文件,通过实现UserProvider和Authenticatable接口,灵活处理用户检索与密码验证,解决认证问题需确保接口方法正确实现并合理配置。

自定义 Laravel 用户提供者允许你使用非 Eloquent 模型或数据库表来验证用户。它通过实现
Illuminate\Contracts\Auth\UserProvider
解决方案
要创建一个自定义用户提供者,你需要完成以下步骤:
创建用户模型: 如果你还没有,创建一个代表用户的类。这个类不需要继承 Eloquent 模型,但它必须实现
Illuminate\Contracts\Auth\Authenticatable
namespace App\Models;
use Illuminate\Contracts\Auth\Authenticatable;
class CustomUser implements Authenticatable
{
protected $id;
protected $username;
protected $password;
protected $attributes = [];
public function __construct(array $attributes = [])
{
$this->attributes = $attributes;
if (isset($attributes['id'])) {
$this->id = $attributes['id'];
}
if (isset($attributes['username'])) {
$this->username = $attributes['username'];
}
if (isset($attributes['password'])) {
$this->password = $attributes['password'];
}
}
public function getAuthIdentifierName()
{
return 'id';
}
public function getAuthIdentifier()
{
return $this->id;
}
public function getAuthPassword()
{
return $this->password;
}
public function getRememberToken()
{
return $this->attributes['remember_token'] ?? null;
}
public function setRememberToken($value)
{
$this->attributes['remember_token'] = $value;
}
public function getRememberTokenName()
{
return 'remember_token';
}
public function setAttribute($key, $value) {
$this->attributes[$key] = $value;
}
public function getAttribute($key) {
return $this->attributes[$key] ?? null;
}
public function __get($key) {
return $this->getAttribute($key);
}
public function __set($key, $value) {
$this->setAttribute($key, $value);
}
}创建用户提供者: 创建一个类来实现
Illuminate\Contracts\Auth\UserProvider
namespace App\Providers;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider;
use App\Models\CustomUser; // 替换为你的用户模型
use Illuminate\Support\Facades\Hash;
class CustomUserProvider implements UserProvider
{
protected $model;
public function __construct(string $model)
{
$this->model = $model;
}
public function retrieveById($identifier)
{
// 从你的数据源检索用户,例如数据库、API等
// 这里只是一个示例,你需要根据你的实际情况进行修改
$user = $this->getUserFromDataSource(['id' => $identifier]);
if ($user) {
return new $this->model($user);
}
return null;
}
public function retrieveByToken($identifier, $token)
{
// 从你的数据源检索用户,并验证令牌
// 同样,这里只是一个示例
$user = $this->getUserFromDataSource(['id' => $identifier, 'remember_token' => $token]);
if ($user) {
return new $this->model($user);
}
return null;
}
public function updateRememberToken(Authenticatable $user, $token)
{
// 更新用户的记住我令牌
// 同样,这里只是一个示例
$this->updateUserRememberToken($user->getAuthIdentifier(), $token);
}
public function retrieveByCredentials(array $credentials)
{
// 从你的数据源检索用户,基于提供的凭据
// 同样,这里只是一个示例
if (empty($credentials) ||
(count($credentials) === 1 &&
array_key_exists('password', $credentials))) {
return null;
}
$query = [];
foreach ($credentials as $key => $value) {
if (! str_contains($key, 'password')) {
$query[$key] = $value;
}
}
$user = $this->getUserFromDataSource($query);
if ($user) {
return new $this->model($user);
}
return null;
}
public function validateCredentials(Authenticatable $user, array $credentials)
{
// 验证用户提供的凭据是否正确
// 同样,这里只是一个示例
$plain = $credentials['password'];
return Hash::check($plain, $user->getAuthPassword());
}
// 模拟从数据源获取用户数据
private function getUserFromDataSource(array $credentials)
{
// 替换为你的实际数据源逻辑
// 例如,从数据库查询、调用API等
$users = [
[
'id' => 1,
'username' => 'testuser',
'password' => Hash::make('password'),
'remember_token' => null,
],
[
'id' => 2,
'username' => 'anotheruser',
'password' => Hash::make('anotherpassword'),
'remember_token' => null,
],
];
foreach ($users as $user) {
$match = true;
foreach ($credentials as $key => $value) {
if ($user[$key] != $value) {
$match = false;
break;
}
}
if ($match) {
return $user;
}
}
return null;
}
// 模拟更新用户记住我令牌
private function updateUserRememberToken($id, $token)
{
// 替换为你的实际数据源更新逻辑
// 例如,更新数据库记录、调用API等
// 这里只是一个示例,没有实际更新操作
}
}注册用户提供者: 在
config/auth.php
'providers' => [
'users' => [
'driver' => 'custom',
'model' => App\Models\CustomUser::class, // 替换为你的用户模型
],
],配置认证守卫: 在
config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],自定义用户提供者可以处理哪些类型的用户数据源?
自定义用户提供者最大的优势在于其灵活性。它可以处理几乎任何类型的用户数据源,包括:
关键在于
retrieveById
retrieveByToken
retrieveByCredentials
validateCredentials
如何处理用户密码的加密和验证?
Laravel 提供了
Hash
Hash::make()
Hash::check()
在
CustomUserProvider
validateCredentials
Hash::check()
public function validateCredentials(Authenticatable $user, array $credentials)
{
$plain = $credentials['password'];
return Hash::check($plain, $user->getAuthPassword());
}确保在用户注册或更新密码时使用
Hash::make()
使用自定义用户提供者进行身份验证时,常见的错误以及如何解决?
在使用自定义用户提供者时,可能会遇到一些常见的错误:
Target [Illuminate\Contracts\Auth\Authenticatable] is not instantiable
Illuminate\Contracts\Auth\Authenticatable
config/auth.php
model
Call to undefined method
Illuminate\Contracts\Auth\Authenticatable
getAuthIdentifierName
getAuthIdentifier
getAuthPassword
getRememberToken
setRememberToken
getRememberTokenName
身份验证失败: 这可能是由于多种原因造成的。 首先,确保你的
retrieveByCredentials
validateCredentials
dd()
Class 'App\Providers\CustomUserProvider' not found
config/app.php
providers
Remember Me 功能不起作用: 确保你的用户模型实现了
getRememberToken
setRememberToken
getRememberTokenName
updateRememberToken
总而言之,自定义用户提供者为 Laravel 身份验证提供了极大的灵活性。 通过正确实现
Illuminate\Contracts\Auth\UserProvider
Illuminate\Contracts\Auth\Authenticatable
以上就是Laravel自定义用户提供者?用户提供者怎样实现?的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号