11363
Laravel 5.0 で標準付属の Auth による User 認証を使っています。  
その場合 Auth::user()->name などで現在ログイン中のユーザーのプロパティが得られますが、  
今回 role というプロパティをもたせ、Auth::user()->role で取得できるようにしたいと考えています。

users テーブルには新しいカラム「role_id」を作り、用意した roles テーブルの id とひもづける予定です。  
SQL文は次のようなものです。

```

    SELECT users.*, roles.name AS role FROM `users` INNER JOIN `roles` ON users.role_id = roles.id
    
```

辿って行くと、「vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php」の
retrieveById() で処理が行われているようなので次のように書き換えて動作することを確認しました。

```

    public function retrieveById($identifier)
    {
        return $this->createModel()->newQuery()
            ->select(['users.*', 'roles.name as role'])
            ->join('roles', 'users.role_id', '=', 'roles.id')
            ->find($identifier);
    
        // return $this->createModel()->newQuery()->find($identifier);
    }
    
```

一応はこれでも目的の動作をしてはいますが、本来は何らかの拡張クラスを作って extend するべきなのでしょうか？  
もしそうであればどのフォルダにどのような形で追加したら良いのでしょうか。  
フレームワークの使い方自体まだ不慣れで良く理解できていません。よろしくお願い致します。
CC BY-SA 3.0
2015-06-12T02:58:32.470
11271
2015-06-15T09:24:16.407
2015-06-15T06:50:32.277
10083
10083
question
php laravel
Laravel 5 の「Auth::user()」のプロパティにJOINしたデータを追加したい
laravelの標準ORMである、Eloquentで実装するのが一般的かと思います。  
Roleモデルを作成し、belongsToMany()メソッドを使って、Userモデルと多対多のリレーションで紐付けます。テーブルは
rolesテーブルと、role_userテーブルを作成します。  
詳細な手順は下記の参考サイトをご覧ください。

参考サイト

  * [初めてのLARAVEL 5 : (33) 多対多のリレーション モデル/DB編](https://laravel10.wordpress.com/2015/03/30/%E5%88%9D%E3%82%81%E3%81%A6%E3%81%AElaravel-5-33-%E5%A4%9A%E5%AF%BE%E5%A4%9A%E3%81%AE%E3%83%AA%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A7%E3%83%B3-%E3%83%A2%E3%83%87%E3%83%ABdb%E7%B7%A8/)
  * [Eloquent: Relationships](http://laravel.com/docs/5.1/eloquent-relationships#many-to-many)
CC BY-SA 3.0
2015-06-14T17:56:15.057
11334
2015-06-14T17:56:15.057
9529
11271
answer
laravelアプリで、userに roleや
Permissionを付与したいということであれば、[zizaco/entrust](https://github.com/Zizaco/entrust)
パッケージを使うもの良いかと思います。

<https://github.com/Zizaco/entrust>
CC BY-SA 3.0
2015-06-14T18:04:05.597
11335
2015-06-14T18:04:05.597
9529
11271
answer
vendor配下はcomposerライブラリのディレクトリになりますので、  
直接ソースコードを編集するのはお勧めしません。  
updateの度に書き換えられますし、  
updateをしないとなりますとバグフィックスなども受けられません。

質問にあるような認証情報を取得できるようにするには、方法はいくつかありますが、  
フレームワークを学ぶ上でも一番のベストプラクティスは認証ドライバーの追加、または拡張です。

その際にどのフォルダに置くか、ですがLaravel5以上であればデフォルトのオートローダがpsr-4に対応していますので、  
ディレクトリやファイルの場所は特に関係ありません。  
ここでは **app/Autheinticate** 配下に作成する例として紹介します。

`Illuminate/Auth/EloquentUserProvider.php`がデフォルトでEloquentを利用する認証クラスになっていますので、  
該当のretrieveByIdメソッドをオーバライドするために、  
`app/Autheinticate/AuthUserProvider.php`としてファイルを作成します。  

```

    <?php
    namespace App\Authenticate;
    
    use Illuminate\Auth\EloquentUserProvider;
    
    class AuthUserProvider extends EloquentUserProvider
    {
    
        /**
         * Retrieve a user by their unique identifier.
         * @param  mixed  $identifier
         * @return \Illuminate\Contracts\Auth\Authenticatable|null
         */
        public function retrieveById($identifier)
        {
            return $this->createModel()->newQuery()
                ->join('roles', 'users.role_id', '=', 'roles.id')
                ->find($identifier, ['users.*', 'roles.name as role']);
        }
    
    }
    
```

次に認証ドライバーとして追加します。(ここではwith_roleという名前にします)  
ドライバー追加はサービスプロバイダーを利用しますので、  
app/Providers配下にサービスプロバイダーを作成します。  

```

    <?php
    namespace App\Providers;
    
    use App\Authenticate\AuthUserProvider;
    use Illuminate\Support\ServiceProvider;
    
    class AuthServiceProvider extends ServiceProvider
    {
    
        /**
         * Register the service provider.
         *
         * @return void
         */
        public function register()
        {
            $this->app['auth']->extend('with_role', function () {
                $model = $this->app['config']['auth.model'];
                return new AuthUserProvider($this->app['hash'], $model);
            });
        }
    }
    
```

サービスプロバイダーからサービスコンテナへは`$this->app`でアクセスできます。  
認証クラスはサービスコンテナにauthという名前で登録されていますので、  
認証クラスへアクセスしてextendメソッドを利用します。  
このメソッドはドライバを追加する場合に利用します。  
(認証、キャッシュ、セッション、データベース、ファイルストレージなどで利用するメソッドです)  
認証に利用するEloquentを継承したクラスをconfig/auth.phpのmodelから取得して、  
作成したAuthUserProviderクラスのコンストラクタに渡す引数を記述します。  
(Illuminate\Auth\EloquentUserProviderを継承しているため)  
作成したApp\Providers\AuthServiceProviderクラスをconfig/app.phpのproviders配列へ追記し、  
最後にconfig/auth.phpのdriverにwith_roleを記述します。

```

    'driver' => 'with_role',
    
```

あとはいつも通り`\Auth::user()`で取得できます。  
ドライバーを追加するメリットとしては、同じように追加したドライバや既存のドライバを

```

    Auth::driver('eloquent')->user();
    Auth::driver('with_role')->user();
    
```

などdriverメソッドを利用してそれぞれの用途に合わせた場面で認証情報を変更したり、  
ログインなども分けることができます。

最新の5.1のマニュアルにはありませんでしたが、下記にも記載されていますので参考にしてみてください。  
5.1でも拡張方法は同様です。  
[Laravel 5.0 公式 | Extending The
Framework](http://laravel.com/docs/5.0/extending)  
[Laravel 5.0 日本語訳 |
フレームワークの拡張](http://readouble.com/laravel/5/0/dev/ja/extending.html)
CC BY-SA 3.0
2015-06-15T05:40:40.713
11363
2015-06-15T09:24:16.407
2015-06-15T09:24:16.407
609
609
11271
answer