我需要使用另一个表和用户创建一个新的“auth”配置。我有一个用于“admin”用户的表和另一个用于普通用户的表。
但是如何使用不同的配置创建另一个Auth
实例?
答案 0 :(得分:31)
在尝试自己解决这个问题时,我找到了一种更简单的方法。我基本上创建了一个自定义ServiceProvider来替换默认的Auth one,它作为Auth的工厂类,并允许您为多种登录类型提供多个实例。我也把它全部放在一个包中,可以在这里找到:https://github.com/ollieread/multiauth
真的很容易使用,只需将app / config / app.php中的AuthServiceProvider替换为Ollieread \ Multiauth \ MultiauthServiceProvider,然后将app / config / auth.php更改为如下所示:
return array(
'multi' => array(
'account' => array(
'driver' => 'eloquent',
'model' => 'Account'
),
'user' => array(
'driver' => 'database',
'table' => 'users'
)
),
'reminder' => array(
'email' => 'emails.auth.reminder',
'table' => 'password_reminders',
'expire' => 60,
),
);
现在你可以像以前一样使用Auth,但稍有不同:
Auth::account()->attempt(array(
'email' => $attributes['email'],
'password' => $attributes['password'],
));
Auth::user()->attempt(array(
'email' => $attributes['email'],
'password' => $attributes['password'],
));
Auth::account()->check();
Auth::user()->check();
它还允许您同时以多个用户类型登录,这是我正在处理的项目的要求。希望它对我以外的其他人有帮助。
更新 - 2014年2月27日
对于那些刚刚接触到这个答案的人,我最近刚刚添加了对提醒的支持,可以采用相同的工厂方式进行访问。
答案 1 :(得分:15)
您可以“模拟”新的Auth类。
Laravel Auth组件基本上是Illuminate\Auth\Guard
类,这个类有一些依赖。
所以,基本上你必须创建一个新的Guard类和一些外观......
<?php
use Illuminate\Auth\Guard as AuthGuard;
class CilentGuard extends AuthGuard
{
public function getName()
{
return 'login_' . md5('ClientAuth');
}
public function getRecallerName()
{
return 'remember_' . md5('ClientAuth');
}
}
...添加ServiceProvider
来初始化此类,传递它的依赖项。
<?php
use Illuminate\Support\ServiceProvider;
use Illuminate\Auth\EloquentUserProvider;
use Illuminate\Hashing\BcryptHasher;
use Illuminate\Auth\Reminders\PasswordBroker;
use Illuminate\Auth\Reminders\DatabaseReminderRepository;
use ClientGuard;
use ClientAuth;
class ClientServiceProvider extends ServiceProvider
{
public function register()
{
$this->registerAuth();
$this->registerReminders();
}
protected function registerAuth()
{
$this->registerClientCrypt();
$this->registerClientProvider();
$this->registerClientGuard();
}
protected function registerClientCrypt()
{
$this->app['client.auth.crypt'] = $this->app->share(function($app)
{
return new BcryptHasher;
});
}
protected function registerClientProvider()
{
$this->app['client.auth.provider'] = $this->app->share(function($app)
{
return new EloquentUserProvider(
$app['client.auth.crypt'],
'Client'
);
});
}
protected function registerClientGuard()
{
$this->app['client.auth'] = $this->app->share(function($app)
{
$guard = new Guard(
$app['client.auth.provider'],
$app['session.store']
);
$guard->setCookieJar($app['cookie']);
return $guard;
});
}
protected function registerReminders()
{
# DatabaseReminderRepository
$this->registerReminderDatabaseRepository();
# PasswordBroker
$this->app['client.reminder'] = $this->app->share(function($app)
{
return new PasswordBroker(
$app['client.reminder.repository'],
$app['client.auth.provider'],
$app['redirect'],
$app['mailer'],
'emails.client.reminder' // email template for the reminder
);
});
}
protected function registerReminderDatabaseRepository()
{
$this->app['client.reminder.repository'] = $this->app->share(function($app)
{
$connection = $app['db']->connection();
$table = 'client_reminders';
$key = $app['config']['app.key'];
return new DatabaseReminderRepository($connection, $table, $key);
});
}
public function provides()
{
return array(
'client.auth',
'client.auth.provider',
'client.auth.crypt',
'client.reminder.repository',
'client.reminder',
);
}
}
在此服务提供商中,我举了一些如何创建“新”密码提醒组件的示例。
现在您需要创建两个新的外观,一个用于身份验证,另一个用于密码提醒。
<?php
use Illuminate\Support\Facades\Facade;
class ClientAuth extends Facade
{
protected static function getFacadeAccessor()
{
return 'client.auth';
}
}
和...
<?php
use Illuminate\Support\Facades\Facade;
class ClientPassword extends Facade
{
protected static function getFacadeAccessor()
{
return 'client.reminder';
}
}
当然,对于密码提醒,您需要在数据库中创建表,以便工作。在此示例中,表名应为client_reminders
,您可以在服务提供商的registerReminderDatabaseRepository
方法中看到。表结构与原始提醒表相同。
之后,您可以像使用ClientAuth
课程一样使用Auth
。 ClientPassword
类的Password
也是如此。
ClientAuth::gust();
ClientAuth::attempt(array('email' => $email, 'password' => $password));
ClientPassword::remind($credentials);
不要忘记将您的服务提供商添加到app/config/app.php
文件中的服务提供商列表中。
<强>更新强>
如果您使用的是Laravel 4.1,则PasswordBroker不再需要Redirect
类。
return new PasswordBroker(
$app['client.reminder.repository'],
$app['client.auth.provider'],
$app['mailer'],
'emails.client.reminder' // email template for the reminder
);
更新2
Laravel 5.2刚刚介绍了multi auth,因此在此版本中不再需要它。
答案 2 :(得分:12)
好的,我遇到了同样的问题,这就是我解决的问题:
实际上在laravel 4中你可以简单地在运行时更改auth配置,这样你就可以在过滤前在App ::中简单地执行以下操作:
if ($request->is('admin*'))
{
Config::set('auth.model', 'Admin');
}
这将使Auth组件在管理员网址中使用管理员模型。但这会导致一个新问题,因为如果您的管理员和用户表中有两个用户具有相同的ID,则登录会话密钥是相同的,如果您之前已登录,则可以登录管理站点普通用户!为了使两个不同的认证完全独立,我做了这个伎俩:
class AdminGuard extends Guard
{
public function getName()
{
return 'admin_login_'.md5(get_class($this));
}
public function getRecallerName()
{
return 'admin_remember_'.md5(get_class($this));
}
}
Auth::extend('eloquent.admin', function()
{
return new AdminGuard(new EloquentUserProvider(new BcryptHasher, 'Admin'), App::make('session.store'));
});
并将代码前的App ::更改为:
if ($request->is('admin*'))
{
Config::set('auth.driver', 'eloquent.admin');
Config::set('auth.model', 'Admin');
}
你可以看到我创建了一个新的auth驱动程序并在Guard类上重写了一些方法,因此它将为管理站点生成不同的会话密钥。然后我更改了管理站点的驱动程序。祝你好运。
答案 3 :(得分:3)
昨天我遇到了同样的问题,最后我创建了一个更简单的解决方案。
我的要求两个不同数据库中有两个不同的表。一个表用于管理员,另一个表用于普通用户。此外,每个表都有自己的散列方式。我最终得到了以下内容(代码也可作为Github上的要点:https://gist.github.com/Xethron/6790029)
创建一个新的UserProvider。我打电话给我的MultiUserProvider.php
<?php
// app/libraries/MultiUserProvider.php
use Illuminate\Auth\UserProviderInterface,
Illuminate\Auth\UserInterface,
Illuminate\Auth\GenericUser;
class MultiUserProvider implements UserProviderInterface {
protected $providers;
public function __construct() {
// This should be moved to the config later...
// This is a list of providers that can be used, including
// their user model, hasher class, and hasher options...
$this->providers = array(
'joomla' => array(
'model' => 'JoomlaUser',
'hasher' => 'JoomlaHasher',
)
'another' => array(
'model' => 'AnotherUser',
'hasher' => 'AnotherHasher',
'options' => array(
'username' => 'empolyee_number',
'salt' => 'salt',
)
),
);
}
/**
* Retrieve a user by their unique identifier.
*
* @param mixed $identifier
* @return \Illuminate\Auth\UserInterface|null
*/
public function retrieveById($identifier)
{
// Returns the current provider from the session.
// Should throw an error if there is none...
$provider = Session::get('user.provider');
$user = $this->createModel($this->providers[$provider]['model'])->newQuery()->find($identifier);
if ($user){
$user->provider = $provider;
}
return $user;
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Auth\UserInterface|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.
// Retrieve the provider from the $credentials array.
// Should throw an error if there is none...
$provider = $credentials['provider'];
$query = $this->createModel($this->providers[$provider]['model'])->newQuery();
foreach ($credentials as $key => $value)
{
if ( ! str_contains($key, 'password') && ! str_contains($key, 'provider'))
$query->where($key, $value);
}
$user = $query->first();
if ($user){
Session::put('user.provider', $provider);
$user->provider = $provider;
}
return $user;
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Auth\UserInterface $user
* @param array $credentials
* @return bool
*/
public function validateCredentials(UserInterface $user, array $credentials)
{
$plain = $credentials['password'];
// Retrieve the provider from the $credentials array.
// Should throw an error if there is none...
$provider = $credentials['provider'];
$options = array();
if (isset($this->providers[$provider]['options'])){
foreach ($this->providers[$provider]['options'] as $key => $value) {
$options[$key] = $user->$value;
}
}
return $this->createModel($this->providers[$provider]['hasher'])
->check($plain, $user->getAuthPassword(), $options);
}
/**
* Create a new instance of a class.
*
* @param string $name Name of the class
* @return Class
*/
public function createModel($name)
{
$class = '\\'.ltrim($name, '\\');
return new $class;
}
}
然后,我通过在app/start/global.php
文件的顶部添加以下行来告诉Laravel我的UserProvider。
// app/start/global.php
// Add the following few lines to your global.php file
Auth::extend('multi', function($app) {
$provider = new \MultiUserProvider();
return new \Illuminate\Auth\Guard($provider, $app['session']);
});
然后,我告诉Laravel在app/config/auth.php
'driver' => 'multi',
现在,当我进行身份验证时,我会这样做:
Auth::attempt(array(
'email' => $email,
'password' => $password,
'provider'=>'joomla'
)
)
然后该类将使用joomlaUser模型,使用joomlaHasher,并且没有forher的选项...如果使用“其他”提供程序,它将包含hasher的选项。
这个课程是为我所需要的而设计的,但可以轻松更改以满足您的需求。
PS:确保自动加载器可以找到MultiUserProvider,否则它将无效。
答案 4 :(得分:1)
我正在使用Laravel 5 native auth来处理多个用户表...
这并不困难,请查看这个要点:
https://gist.github.com/danielcoimbra/64b779b4d9e522bc3373
更新:对于Laravel 5,如果您需要更强大的解决方案,请尝试以下方法:
https://github.com/sboo/multiauth
丹尼尔