身份validation2个不同的表

我需要创build一个新的“auth”configuration与另一个表和用户。 我有一个“admin”用户表和普通用户的另一个表。

但是我怎样才能创build另一个不同configuration的Auth实例?

您可以“模拟”一个新的Auth类。

Laravel Auth组件基本上是Illuminate\Auth\Guard类,而这个类有一些依赖关系。

所以,基本上你必须创build一个新的卫兵class和一些门面…

 <?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', ); } } 

在这个服务提供商中,我举了一些如何创build“新”密码提醒组件的例子。

现在您需要创build两个新的外墙,一个用于validation,一个用于密码提示。

 <?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'; } } 

当然,对于密码提醒,您需要在数据库中创build表,才能正常工作。 在这个例子中,表名应该是client_reminders ,正如你可以在服务提供者的registerReminderDatabaseRepository方法中看到的那样。 表格结构与原始提醒表格相同。

之后,您可以像使用Auth类一样使用ClientAuthClientPasswordPassword类一样。

 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刚刚推出了多重authentication ,所以这个版本不再需要这个了。

在尝试自己解决这个问题的时候,我发现了一个更简单的方法。 我基本上创build了一个自定义的ServiceProvider来replace默认的Auth,它作为一个Auth的工厂类,允许你为多个logintypes创build多个实例。 我也卡在一个可以在这里find的包: https : //github.com/ollieread/multiauth

这真的很简单,只需用applet / config / app.php中的AuthServiceProviderreplace为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(); 

它还允许您同时以多个用户typeslogin,这是我正在进行的项目的一项要求。 希望它能帮助别人。

更新 – 27/02/2014

对于那些刚刚遇到这个问题的人来说,我刚刚添加了对提醒的支持,这些提醒可以用同样的工厂风格进行访问。

好吧,我有同样的问题,这是我如何解决它:

实际上,在laravel 4中,你可以简单地在运行时改变authconfiguration,这样做就可以简单地在你的App :: beforefilter中执行以下操作:

 if ($request->is('admin*')) { Config::set('auth.model', 'Admin'); } 

这将使Auth组件在pipe理地址中使用pipe理员模型。 但这会导致一个新的问题,因为如果你的pipe理员和用户表中有两个用户具有相同的ID,login会话密钥是相同的,你将能够login到pipe理网站,如果你之前已经login普通用户! 所以为了使两个不同的身份validation完全独立,我做了这个诀窍:

 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 :: before代码更改为:

 if ($request->is('admin*')) { Config::set('auth.driver', 'eloquent.admin'); Config::set('auth.model', 'Admin'); } 

你可以看到我创build了一个新的auth驱动程序,并在Guard类中重写了一些方法,这样就会为pipe理站点生成不同的会话密钥。 然后我更改了pipe理网站的驱动程序。 祝你好运。

我昨天遇到了同样的问题,最后我创build了一个更简单的解决scheme。

我的要求在两个不同的数据库中的2个不同的表。 一个表是pipe理员,另一个表是普通用户。 而且,每个表都有自己的散列方式。 我结束了以下(代码也可以作为Github上的要点: https : //gist.github.com/Xethron/6790029 )

创build一个新的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', 

现在,当我authentication的时候,我这样做:

 Auth::attempt(array( 'email' => $email, 'password' => $password, 'provider'=>'joomla' ) ) 

然后,这个类将使用joomlaUser模型,使用joomlaHasher,并且没有选项。如果使用另一个提供者,它将包含hasher的选项。

这门课是为我所需要的而devise的,但可以很容易地改变以适应您的需求。

PS:确保自动加载器可以findMultiUserProvider,否则它将不起作用。

我正在使用Laravel 5 native auth来处理多个用户表…

这并不难,请检查这个要点:

https://gist.github.com/danielcoimbra/64b779b4d9e522bc3373

更新:对于Laravel 5,如果你需要一个更强大的解决scheme,试试这个包:

https://github.com/sboo/multiauth

丹尼尔