はじめに。
アドベントカレンダー初参加のかわおと申します。
よろしくお願いします。
今回は、Sentry2のLaravel4での使用例を紹介したいと思います。
ユーザ管理について
Laravel4にて、ユーザ認証パッケージ Sentry2の eloquentによる拡張を行いました。
eloquentモデルで扱い、モデルを拡張をすることで、追加用件の要望にこたえられ、強度の高いユーザ認証システムを構築することができます。
その一例として、priorityの追加を行う手順を追って記します。
Sentryの開発チームは現在後継のSentinel というフリーミアムライセンスのライブラリを更新されておりますが、
今回紹介いたします Sentryの最終更新は1年前ほどということで、しばらくは現役でSentry2を扱うには問題ないと考えております。
基本的にはマニュアルに書かれたとおりに進めていけば、セットアップ、構築は可能です。Composerから導入してください。
https://cartalyst.com/manual/sentry/2.1#laravel-4
Sentryが標準機能でできること
- ユーザは複数グループに所属可能。多対多の関係性で紐づけられる。
- ログイン失敗時には規定回数でパスワードロックがかかる(Throttleに格納されます)
- 少々コードは必要ですが、リマインダーメールへの対応()。
- 権限設定を個人とグループに持たせることができ、権限の全所持する重ねがけが可能。
など。盤石です。
Sentryのライブラリの拡張で行えること
- migration時に、カスタムでテーブル構成を定義できます。
- 当然、eloquentにてユーザのカラムの拡張を行い、ユーザ情報のカスタムを行うことはできます。
DBでリレーションなど追加の要件がなければ、modelのカスタムを行わずとも扱えます。 - グループ間の関係は、users_groups テーブルなので、マイグレーション側のカスタムで対応されます。
グループごとのユーザの表示に優先順位をつけたい場合、
どうしてもグループとユーザ間の関係に優先順位をつけないとならないため、。
追加記述するべき箇所について
sentryのライブラリはそのままに、configで見る場所を変える、migrationの設定の
Laravel 4 + Sentry 2でデフォルトのテーブル名を変更する の記事を参考にさせて頂いております。
migrationのコピー、変更
migration を行うファイルは、Cartalyst/sentry/src/migrations 以下にあります。
pivot tableですが、こちらにpriorityの行を追加しました。
...
class CreateUsersGroups extends Migration {
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('users_groups', function(Blueprint $table)
{
//
$table->integer('user_id')->unsigned();
$table->integer('group_id')->unsigned();
$table->integer('priority')->unsigned(); // ここに追加
...
modelのコピー
Sentryのフォルダーにあるeloquentより、モデルを継承しましょう。
sentry/src/Cartalyst/Sentry/Users/Eloquent のように各テーブル名の奥にEloquentと言うフォルダの中にあります。
Group,Users,users_groupsをプロジェクトのmodelsディレクトリで継承する形で記述してください。
宣言だけでもひとまず今は問題はないです。
class User extends Cartalyst\Sentry\Users\Eloquent\User {
...
class Group extends Cartalyst\Sentry\Groups\Eloquent\Group {
...
modelの変更
グループの呼び出しに際して、->withPivot('priority')->orderBy('priority', 'desc')
を加えることで優先順位のソートをかけることが出来るようになります。
...
...
public function addGroupWithPivot(GroupInterface $group, array $pivot = array() )
{
if ( $this->inGroup($group))
{
$this->groups()->detach($group);
}
// pivotで関連する値をあるなら入れる
$this->groups()->attach($group, $pivot);
$this->invalidateUserGroupsCache();
$this->invalidateMergedPermissionsCache();
return true;
}
/**
* Returns the relationship between users and groups.
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function groups()
{
// return $this->belongsToMany(static::$groupModel, static::$userGroupsPivot);
return $this->belongsToMany(static::$groupModel, static::$userGroupsPivot)->withPivot('priority')->orderBy('priority', 'desc');
}
...
訂正:2015/1/17 下記のようにsyncで変更を行うと、グループを複数組み合わせた場合に不具合が出ますので削除->再度作成の呼び出し順に変更しました。
// すでにグループに登録されている場合も同様にsyncで代入する
$this->groups()->sync(array($group->id => $pivot));
コンフィグの設定
Sentryへの反映にはコンフィグ設定が必要です。
...
//'model' => 'Cartalyst\Sentry\Groups\Eloquent\Group',
'model' => 'Group', // カスタムモデルで読み書きさせる
...
//'model' => 'Cartalyst\Sentry\Users\Eloquent\User',
'model' => 'User', // カスタムモデルで読み書きさせる
...
ソート順の設定については、
if ( $user->addGroupWithPivot($staffGroup, array('priority' => $staffstatus['priority'])) ) {
のように modelに定義した addGroupWithPivot で行えます。
おわりに
駆け足となってしまいましたが、Sentryというモジュールは一度慣れてしまえば、基本的な機能は任せられ、業務案件にも適したレベルのカスタムまで行えるため、恩恵を受けることが出来ます。
是非ご検討ください!
明日は@yashikawa さんです。