Laravel5.6 でユーザーとコミュニティが多対多の関係を持つアプリを制作しています。
認証をカスタマイズしているのですが、アプリをけっこう作り込んでから困った事になっています。
##table設計
###users
ユーザーはユニークIDを持つ
###community_users
中間tableでユニークIDと userと community のIDを持つ
###community_user_status
上記中間tableと1対1で紐付いた ユーザーのcomuunity内でのステータス情報を持つ
###community
コミュニティ毎のユーザーの情報を持つ(管理権限等)
ユーザーはコミュニティ毎に異なるユーザーステータスを保持しています。
当初は以下のサイトを参考に、認証時に複数のtableを Join をした値を取得し、値を保持することには成功しました。
Laravel 5.2 Auth::user() に他テーブルのJOINしたデータを追加する。
これで以下の様な方法で値を取得し処理を書いていました。
Auth::user()->role == "Admin"
しかし、いざユーザーが二つ目のコミュニティにログインしようとする時点で詰まってしまいました。
ログイン認証が行われる際以下の処理が走ります。
app\Http\Controllers\Auth\LoginController.php
PHP
1 public function authenticate(Request $request) 2 { 3 4 $credentials = array( 5 'unique_name' => $request->unique_name, 6 'password' => $request->password, 7 ); 8 // 'community_user.id' => $community_user_id, 9 10 // 認証許可 11 if (Auth::attempt($credentials)) { 12 //認証済み後の処理等 13 ] 14 }
上記のAuth::attempt($credentials)
の処理が走る際、以下に書いた処理が走り、 Auth::user()に取得した値が入る事になっています。
app\Providers\AuthUserProvider.php namespace App\Providers; use Illuminate\Auth\EloquentUserProvider; use Illuminate\Support\Facades\Log; class AuthUserProvider extends EloquentUserProvider { public function retrieveById($identifier) { $result = $this->createModel()->newQuery() ->Join('community_user', 省略) ->Join('communities_users_statuses', 省略) ->Join('roles', 省略) ->select([ 'users.*', 'community_user.*', 'roles.*', ]) ->where('community_user.id', $identifier); return $result; } }
しかしこのメソッドの引数 $identifier
に入るのはIDは users tableのユニークIDであり、本来取得に必要な中間table(community_user)のユニークIDにはならない為、ユーザーが複数のコミュニティに登録してしまうと。このクエリビルダだと、複数のレコードが存在した場合、どのレコードを拾うべきか判断がつかないのです。
そこで認証の際に使うModelを呼び出しの時点でリレーションが出来上がったモデル読み込む等して解決できないか?とか悩んでいます。
config\auth.php
'providers' => [ 'users' => [ 'driver' => 'auth_ex', 'model' => App\User::class, ],
上記の呼び出し対象は 最初からある User Authenticatableですが、ここと、呼び出し先のModelに上手い書き方をして、結合した状態のモデルを呼び出せればいいのですが、やり方がわかりません。app\User.php
に上手い書き方をすれば解決する様な気もするのですが…。
また、別の方法として、上記のモデルを CommunityUser 等に切り替えて、認証に使ってみましたが、 ユーザーのユニークな値を保持していない為一意の情報を取得できず認証できませんでした。
また、認証の拡張での方法も探ってみたのですが、理解が追い付かずです。
Laravel 5.dev フレームワークの拡張
上記ページの 認証 の部分を見て、これをどこに書き、中に何を入れるべきなのかが理解できませんでした。
Auth::extend('riak', function($app) { // Return implementation of Illuminate\Contracts\Auth\UserProvider });
また、UserProvider
にある以下のメソッドもapp\Providers\AuthUserProvider.php
にて、retrieveById($identifier)
と、併用または代用として使ってみましたが、やはりうまくいきません。
public function retrieveByCredentials(array $credentials);
こいつはapp\Providers\AuthUserProvider.php
に書けば認証時にオーバーライドされて処理が走る所までは掴み、 認証時の呼び出しModelを変えて色々試しましたがやはり駄目でした。
という事でこの辺のうまい解決方法やヒント等を頂けると大変助かります。
単純に Auth::user() に値を追加する等も方法でもあればいいのですが…。
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/11/11 15:44
2018/11/11 18:32