我想创建身份验证机制,而不需要数据库,其中只有一个知道正确用户名和密码(我会硬编码)的人(管理员)才能登录。我仍然想使用Auth :: attempt(),Auth :: check()和其他函数。
我发现我可以创建自己的User driver,但在我看来应该有更简单的东西。
也许这不是一个很好的解决方案,但我想尽可能简单的网站。
答案 0 :(得分:4)
似乎应该只有更简单的东西,但事实上,如果你想扩展身份验证系统,那就像你可以得到的那样简单。您通过Auth
外观使用的所有方法(如attempt
,check
等)都在Illuminate\Auth\Guard
类中实现。此类需要将UserProviderInterface
实现注入构造函数才能工作。这意味着为了使用Auth
外观,您需要使用已经实现的DatabaseUserProvider
或EloquentUserProvider
,或者实现自己的提供程序来处理您想要的简单登录。
虽然您链接的文章可能看起来很冗长,但为了达到您的需求,您可能会在提供程序中使用比您想象的更少的代码。以下是我认为您需要的内容:
1。在app/config/auth.php
将驱动程序更改为simple
并附加所需的登录凭据:
'driver' => 'simple',
'credentials' => array(
'email' => 'user@email.com',
'password' => 'yourpassword'
)
2。在名为app
的{{1}}目录中创建一个包含以下代码的文件:
SimpleUserProvider.php
3. 最后,您需要使用身份验证系统注册新的提供程序。您可以将其附加到use Illuminate\Auth\UserInterface;
use Illuminate\Auth\GenericUser;
use Illuminate\Auth\UserProviderInterface;
class SimpleUserProvider implements UserProviderInterface {
protected $user;
public function __construct(array $credentials)
{
$this->user = new GenericUser(array_merge($credentials, array('id' => null)));
}
// If you only need to login via credentials the following 3 methods
// don't need to be implemented, they just need to be defined
public function retrieveById($identifier) { }
public function retrieveByToken($identifier, $token) { }
public function updateRememberToken(UserInterface $user, $token) { }
public function retrieveByCredentials(array $credentials)
{
return $this->user;
}
public function validateCredentials(UserInterface $user, array $credentials)
{
return $credentials['email'] == $user->email && $credentials['password'] == $user->password;
}
}
文件:
app/start/global.php
这应该为您提供一个简单的(无数据库)用户身份验证,同时仍然可以使用Laravel的外观。
答案 1 :(得分:0)
接受的答案对我不起作用。每次登录时,登录成功,但在 /home
页面时,我再次重定向到登录页面。
我发现这是因为用户没有作为经过身份验证的用户存储在会话中。为了解决这个问题,我必须在 getAuthIdentifier
模型类中实现 User
方法并实现 retrieveById
方法。
我还调整了我的解决方案以支持多个硬编码用户(假设电子邮件是唯一的,因此我们也可以将其用作用户的 ID):
1. 在 app/config/auth.php
中:
'providers' => [
'users' => [
'driver' => 'array',
],
],
'credentials' => [
'userA@email.com' => 'passA',
'userB@email.com' => 'passB',
]
2.UserProvider
:
use \Illuminate\Auth\GenericUser;
use \Illuminate\Contracts\Auth\UserProvider;
use \Illuminate\Contracts\Auth\Authenticatable;
class ArrayUserProvider implements UserProvider
{
private $credential_store;
public function __construct(array $credentials_array)
{
$this->credential_store = $credentials_array;
}
// IMPORTANT: Also implement this method!
public function retrieveById($identifier) {
$username = $identifier;
$password = $this->credential_store[$username];
return new User([
'email' => $username,
'password' => $password,
]);
}
public function retrieveByToken($identifier, $token) { }
public function updateRememberToken(Authenticatable $user, $token) { }
public function retrieveByCredentials(array $credentials)
{
$username = $credentials['email'];
// Check if user even exists
if (!isset($this->credential_store[$username])) {
return null;
}
$password = $this->credential_store[$username];
return new GenericUser([
'email' => $username,
'password' => $password,
'id' => null,
]);
}
public function validateCredentials(Authenticatable $user, array $credentials)
{
return $credentials['email'] == $user->email && $credentials['password'] == $user->getAuthPassword();
}
}
3. 在 app/Providers/AuthServiceProvider
中:
use Illuminate\Support\Facades\Auth;
class AuthServiceProvider extends ServiceProvider
{
...
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
Auth::provider('array', function($app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new ArrayUserProvider($app['config']['auth.credentials']);
});
}
}
4. 在 User.php(模型)中:
class User extends Authenticatable
{
...
public function getAuthIdentifier()
{
return $this->email;
}
}
对于每个感兴趣的人,为什么需要上述补充:
当您登录时,会调用 login
中的方法 Illuminate\Auth\SessionGuard
。在此方法中,您会发现,用户的标识符存储在带有 $this->updateSession($user->getAuthIdentifier())
的会话中。因此我们需要在我们的用户模型中实现这个方法。
当您在控制器中添加 $this->middleware('auth')
时,会调用 authenticate()
中的方法 Illuminate\Auth\Middleware\Authenticate
。这再次调用 $this->auth->guard($guard)->check()
来检查用户是否已通过身份验证。 check()
方法仅测试会话中是否存在用户(请参阅 Illuminate\Auth\GuardHelpers
)。它通过调用守卫的 user()
方法来做到这一点,在本例中又是 SessionGuard
。在 user()
方法中,通过获取会话中存储的 id 并调用 retrieveById
获取用户来检索用户。