我是PHP和Laravel的新手,我来自 Java。
我正在尝试按照本教程来实现自定义用户提供程序:
https://blog.georgebuckingham.com/laravel-52-auth-custom-user-providers-drivers/
我简要解释一下我需要什么:我的Laravel应用程序只是一个前端应用程序,所有的业务逻辑,包括用户身份验证,都是由一个暴露 REST Web 服务的 Java 后端应用程序执行的。
执行呼叫:
http://localhost:8080/Extranet/login
并将用户名和密码作为基本身份验证传递,我获得了一个代表已登录用户的 JSON 响应:
{
"userName": "Painkiller",
"email": "painkiller@gmail.com",
"enabled": true
}
因此,在我的 Laravel 应用程序中,我必须执行此调用,然后解析之前返回的 JSON 对象,以将经过身份验证的对象生成到前端应用程序会话中。
我认为以前的自定义用户提供程序是更简洁、最自然的解决方案,但是我发现了一些困难,并且我对如何在我的项目中做到这一点有很多疑问。
我正在使用Larave 5.3版本。
我已经完成了以下步骤(按照上一个教程并尝试使其适应我的需要):
1) 第 1 阶段:注册您的自定义用户提供程序:
我已经创建了我的服务提供者,我在其中注册了 mycustom 身份验证用户提供者(用于通过 Web 服务执行我的自定义登录的自定义组件)。
所以在我的 Laravel 项目的app目录中,我创建了Authentication子目录,在这里我放了这个扩展ServiceProvider的AuthServiceProvider:
<?php
namespace App\Authentication;
use Auth;
use App\Authentication\UserProvider;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider {
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Auth::provider('our_provider', function ($app, array $config) {
return new UserProvider();
});
}
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
}
这只是注册您的用户提供程序/驱动程序,使其可通过 our_provider 键在 config/auth.php 文件中使用。
第一个疑问:将鼠标传递给:
use Auth;
结果是Undefined class Auth,为什么?在我看来,它没有在以前的代码中使用,可能是教程包含错误或者我遗漏了什么?
然后我将此服务注册到我的config/app.php文件中:
这是此文件的提供者部分:
'providers' => [
/*
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class,
Illuminate\Cache\CacheServiceProvider::class,
Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
Illuminate\Cookie\CookieServiceProvider::class,
Illuminate\Database\DatabaseServiceProvider::class,
Illuminate\Encryption\EncryptionServiceProvider::class,
Illuminate\Filesystem\FilesystemServiceProvider::class,
Illuminate\Foundation\Providers\FoundationServiceProvider::class,
Illuminate\Hashing\HashServiceProvider::class,
Illuminate\Mail\MailServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class,
Illuminate\Pagination\PaginationServiceProvider::class,
Illuminate\Pipeline\PipelineServiceProvider::class,
Illuminate\Queue\QueueServiceProvider::class,
Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class,
/*
* Package Service Providers...
*/
//
/*
* Application Service Providers...
*/
App\Providers\AppServiceProvider::class,
App\Providers\AuthServiceProvider::class,
// App\Providers\BroadcastServiceProvider::class,
App\Providers\EventServiceProvider::class,
App\Providers\RouteServiceProvider::class,
App\Authentication\AuthServiceProvider::class,
],
如您所见,此数组包含我的App\Authentication\AuthServiceProvider::class,代表以前的ServiceProvider。这是对的吗?
2:第 2 阶段:更新配置以使用新驱动程序:
我告诉我的 Laravel 应用程序使用以前的用户提供程序,所以我进入config/auth.php配置文件并设置我的提供程序:
'providers' => [
'users' => [
'driver' => 'our_provider',
],
],
为了完整起见,我发布了config/auth.php的全部内容,以便您查看是否还有其他错误:
<?php
return [
/*
|--------------------------------------------------------------------------
| Authentication Defaults
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
/*
|--------------------------------------------------------------------------
| Authentication Guards
|--------------------------------------------------------------------------
|
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
/*
|--------------------------------------------------------------------------
| User Providers
|--------------------------------------------------------------------------
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
/*
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
*/
'providers' => [
'users' => [
'driver' => 'our_provider',
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
/*
|--------------------------------------------------------------------------
| Resetting Passwords
|--------------------------------------------------------------------------
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [
'users' => [
'provider' => 'users',
'table' => 'password_resets',
'expire' => 60,
],
],
];
3)第三阶段:创建用户类:
我认为这类似于一个模型对象,它将包含从我的 Web 服务接收到的数据(如果用户可以登录系统)。
因此,如果我没有遗漏某些内容,则它必须包含这样的结构(用户名、电子邮件、ebabled 字段):
{
"userName": "Painkiller",
"email": "painkiller@gmail.com",
"enabled": true
}
根据教程,这个用户类必须实现 Laravel Illuminate\Contracts\Auth\Authenticatable 接口。
因此,在/app/Authentication类(包含之前的AuthServiceProvicer类的同一类)中,我将这个User类实现了Authenticatable接口:
<?php
namespace App\Authentication;
use Illuminate\Contracts\Auth\Authenticatable;
class User implements Authenticatable {
/**
* @return string
*/
public function getAuthIdentifierName()
{
// Return the name of unique identifier for the user (e.g. "id")
}
/**
* @return mixed
*/
public function getAuthIdentifier()
{
// Return the unique identifier for the user (e.g. their ID, 123)
}
/**
* @return string
*/
public function getAuthPassword()
{
// Returns the (hashed) password for the user
}
/**
* @return string
*/
public function getRememberToken()
{
// Return the token used for the "remember me" functionality
}
/**
* @param string $value
* @return void
*/
public function setRememberToken($value)
{
// Store a new token user for the "remember me" functionality
}
/**
* @return string
*/
public function getRememberTokenName()
{
// Return the name of the column / attribute used to store the "remember me" token
}
}
怀疑:教程示例仅在此类中放置了存根方法,我没有令牌,我想我只想检索以前的用户名、电子邮件、ebabled 字段。所以我认为这门课是不完整的。我到底要做什么?创建这 3 个字段(代表我的 Web 服务返回的用户信息)和相关的 getter 方法?是它还是我错过了什么?
4) 第 4 阶段:创建一个 UserProvider 类:
在第一阶段,我有一个回调函数,它返回一个App\Authentication\UserProvider的实例,这个类用于检索我们的用户 App\Authentication\User 的实例。
这个类必须实现Illuminate\Contracts\Auth\UserProvider接口。在我看来,必须实现的方法将包含检索我的用户信息的逻辑(因此在我必须进行 Web 服务调用的特定情况下)。
所以在同一个app/Authentication目录中,我把这个UserProvider实现了Illuminate\Contracts\Auth\UserProvider接口,这是我的代码:
<?php
namespace App\Authentication;
use Illuminate\Contracts\Auth\Authenticatable;
use Illuminate\Contracts\Auth\UserProvider as IlluminateUserProvider;
use GuzzleHttp\Client;
use function GuzzleHttp\json_encode;
use function GuzzleHttp\json_decode;
class UserProvider implements IlluminateUserProvider
{
public function retrieveById($identifier)
{
// TODO: Implement retrieveById() method.
}
public function retrieveByToken($identifier, $token)
{
// TODO: Implement retrieveByToken() method.
}
public function updateRememberToken(Authenticatable $user, $token)
{
// TODO: Implement updateRememberToken() method.
}
public function retrieveByCredentials(array $credentials)
{
// TODO: Implement retrieveByCredentials() method.
$client = new Client(); //GuzzleHttp\Client
$response = $client->post('http://localhost:8080/Extranet/login',
[
'auth' => [
'Painkiller',
'pswd'
]
]);
}
public function validateCredentials(Authenticatable $user, array $credentials)
{
// TODO: Implement validateCredentials() method.
}
}
所以我认为我必须把我的网络服务调用放在这个方法retrieveByCredentials()中,这个:
public function retrieveByCredentials(array $credentials)
{
// TODO: Implement retrieveByCredentials() method.
$client = new Client(); //GuzzleHttp\Client
$response = $client->post('http://localhost:8080/Extranet/login',
[
'auth' => [
'Painkiller',
'pswd'
]
]);
}
为了简单起见,此时我已经硬编码了由执行 http 请求的 Web 服务返回的现有用户的凭据,因此对于用户在登录表单中插入的任何凭据,将始终检索该用户(我想做一个测试...然后我将与插入的凭据集成)。
好的,这是我在本教程之后理解的逻辑,它是正确的还是我遗漏了什么?
然后我通过语句php artisan serve启动我的 Laravel 项目,但我收到以下错误消息:
Andrea@Andrea-PC MINGW64 ~/Documents/Betrivius/WorkSpace/betriviusExtranet (master)
$ php artisan serve
PHP Fatal error: Class 'App\Providers\AuthServiceProvider' not found in C:\Users\Andrea\Documents\Betrivius\WorkSpace\betriviusExtranet\vendor\laravel\framework\src\Illuminate\Foundation\ProviderRepository.php on line 146
[Symfony\Component\Debug\Exception\FatalErrorException]
Class 'App\Providers\AuthServiceProvider' not found
为什么?怎么了?我错过了什么?我该如何解决这个问题?