Laravel 4 - 硬编码身份验证
Posted
技术标签:
【中文标题】Laravel 4 - 硬编码身份验证【英文标题】:Laravel 4 - Hardcoded authentication 【发布时间】:2015-07-22 12:25:03 【问题描述】:我想创建身份验证机制不需要数据库,只有一个知道正确用户名和密码(我会硬编码)的人(管理员)才能登录。我还是想用Auth::attempt()、Auth::check()等函数。
我发现我可以创建自己的User driver,但在我看来应该有更简单的东西。
也许这不是很好的解决方案,但我希望网站尽可能简单。
【问题讨论】:
尽可能简单意味着您可以简单地扩展attempt
和check
方法并实现一个简单的比较器功能,该功能只需检查请求输入是否正确组合了用户+通行证。
【参考方案1】:
接受的答案对我不起作用。每次登录都是成功的,但是在/home
页面时,我又被重定向到了登录页面。
我发现这是由于用户没有作为经过身份验证的用户存储在会话中。为了解决这个问题,我必须在 User
模型类中实现 getAuthIdentifier
方法,并且还要实现 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;
更多信息:
对于所有感兴趣的人,为什么需要上述补充:
登录时会调用Illuminate\Auth\SessionGuard
中的login
方法。在这个方法中你会发现,用户的标识符存储在会话中$this->updateSession($user->getAuthIdentifier())
。因此我们需要在我们的用户模型中实现这个方法。
当您在控制器中添加$this->middleware('auth')
时,会调用Illuminate\Auth\Middleware\Authenticate
中的方法authenticate()
。这再次调用$this->auth->guard($guard)->check()
来检查用户是否经过身份验证。 check()
方法仅测试会话中是否存在用户(请参阅Illuminate\Auth\GuardHelpers
)。它通过调用守卫的user()
方法来做到这一点,在这种情况下又是SessionGuard
。在user()
方法中,获取用户的方法是获取session中存储的id,调用retrieveById
获取用户。
【讨论】:
【参考方案2】:看起来应该有一些更简单的东西,但实际上,如果您想扩展身份验证系统,那就很简单了。您通过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
目录中创建一个名为 SimpleUserProvider.php
的文件,其中包含以下代码:
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;
3. 最后,您需要向身份验证系统注册新的提供商。您可以将其附加到 app/start/global.php
文件中:
Auth::extend('simple', function($app)
return new SimpleUserProvider($app['config']['auth.credentials']);
);
这应该给你一个简单的(无数据库)用户身份验证,同时仍然能够使用 Laravel 的外观。
【讨论】:
谢谢,它成功了(几乎:))。我只需要将app_path() . '/components',
添加到 ClassLoader::addDirectories
并将 SimpleUserProvider
添加到 app/components
目录。
其实我可以通过Auth::attemp
,但是Auth::check
总是返回false
,即我总是客人。这是我的代码 sn-p:pastebin以上是关于Laravel 4 - 硬编码身份验证的主要内容,如果未能解决你的问题,请参考以下文章