Sentry is an amazing auth system. But I really need a feature: multiple user types in the same app. And I cannot separate those in groups, because they have different table columns. After 2 days burning my head, I think I found a good solution. The magic is duplicate SentryServiceProvider with new different settings.
This was tested on Laravel 4.0 and Sentry 2. If you're using other version of Sentry, my suggestion is to follow same steps from this gist but use your local files instead copying files from here.
Lets suppose we have a fresh Sentry install with default User ambient. Now we want another ambient called Admin, with new model and different settings. How to do:
Let's create one model called Admin for our new ambient. Just create an empty model and extend it to the Sentry user.
<?php
namespace App\Models;
use Eloquent;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class Admin extends \Cartalyst\Sentry\Users\Eloquent\User implements UserInterface, RemindableInterface {
protected $table = 'admins';
protected $guarded = array(
);
protected $fillable = array(
);
public static $rules = array(
);
/**
* sentry methods
*/
public function groups(){ return $this->belongsToMany('Cartalyst\Sentry\Groups\Eloquent\Group', 'admins_groups'); }
public function getAuthIdentifier(){ return $this->getKey(); }
public function getAuthPassword(){ return $this->password; }
public function getReminderEmail(){ return $this->email; }
}
Create a folder called app/lib and add in composer autoload. In this folder, create this structure:
/app/lib
/SentryMods
SentryAdmin.php
SentryAdminServiceProvider.php
Now we copy contents from original Sentry files just changing some sentry.admin names.
#####SentryAdmin.php
<?php namespace Lib\SentryMods;
use Illuminate\Support\Facades\Facade;
class SentryAdmin extends Facade {
protected static function getFacadeAccessor(){ return 'sentry.admin'; }
}
#####SentryAdminServiceProvider.php
// check attached file to this gist
In the file app/config/cartalyst/sentry/config.php
, add this lines.
Here is the magic. Here we can choose settings for the new sentry provider.
You can change anything, but I've tested only changing the user model.
'admin'=>array(
'driver' => 'eloquent',
'hasher' => 'native',
'groups' => array(
'model' => 'Cartalyst\Sentry\Groups\Eloquent\Group',
),
'cookie' => array(
'key' => 'cartalyst_sentry',
),
'users' => array(
'model' => 'App\Models\Admin',
'login_attribute' => 'login',
),
'throttling' => array(
'enabled' => true,
'model' => 'Cartalyst\Sentry\Throttling\Eloquent\Throttle',
'attempt_limit' => 5,
'suspension_time' => 15,
),
),
I created a migration to run after the migrate of sentry package. This is called sentrymods and copies original tables for the new ambient. This migration can resolves too some adjustments for sentry tables, like adding new columns.
public function up()
{
DB::statement('CREATE TABLE admins LIKE users');
DB::statement('CREATE TABLE admins_groups LIKE users_groups');
Schema::table('admins', function($table){
$table->string('login')->nullable();
$table->softDeletes();
});
Schema::table('admins_groups', function($table){
$table->renameColumn('user_id', 'admin_id');
});
}
Now you have two Sentry ambients working. Then, just use SentryAdmin when you want :) Try this little test:
print_r(Sentry::getUserProvider());
print_r(SentryAdmin::getUserProvider());
The new one prints the default sentry. It will show the default settings. The second will shows our new sentry ambient with different settings. Something like:
// Cartalyst\Sentry\Users\Eloquent\Provider
// Object (
// [model:protected] => App\Models\Admin
// [hasher:protected] => Cartalyst\Sentry\Hashing\NativeHasher
// )
<?php
use App\Models\User;
use Lib\SentryMods\SentryAdmin;
use Lib\SentryMods\SentryAdminServiceProvider;
class SentryTableSeeder extends Seeder {
public function run()
{
$group_admin = SentryAdmin::getGroupProvider()->create(array('name'=>'Admins', 'permissions'=>array('admin'=>1)));
$user = SentryAdmin::getUserProvider()->create(array(
'email' => 'admin@admin.com',
'login' => 'admin',
'password' => 'admin',
'first_name'=>'Leandro', 'last_name'=>'Abdalla', 'activated'=>1,
));
$user->addGroup($group_admin);
}
}
````
**More than 2 ambients?** Just follow the same steps :)
**Remember that you can use this approach to customize the Group class too.**
#### Better solution?
Let me know! I'm including this feature in many projects!
Thanks for Ben of Cartalyst staff with the initial help here: http://help.cartalyst.com/discussions/questions/110-how-to-use-multiple-configurations-of-sentry-in-the-same-laravel-4-app-one-for-public-and-one-for-admin-area
is this working fine for laravel 4.1 and sentry 3?
Can i use this without any issues for now?