マルチAuth実装としてusersテーブル以外のパスワード情報を変更する



[前回書いたマルチAuthの記事](https://qiita.com/maejima_f/items/e153c097e2912d2d75c1)の続きです。
マルチAuthの実装によって別のテーブルに登録されているパスワード情報を変更する方法をまとめます。

*auth.phpにてガードの設定が記述されていることが前提です。

# 動作環境について
OS:macOS High Sierra
version: 10.13.6

Docker(Engine):18.09.0


#### 対象ブラウザ
GoogleChrome:71以上

#### 環境
centOS:7.5
Laravel:5.6
PHP:7.2
MySQL:5.7
APache2.4

# 参考資料
[Laravel5.5のメール送信をMailgun API(無料)で行う～アカウント開設、DNS設定からMailableクラスでの送信まで～](https://www.ritolab.com/entry/39)
[Laravel5.7: 日本語のパスワードリセット用のメールを送信する](https://qiita.com/sutara79/items/0ea48847f5565aacceea)
[Laravel 5.6 パスワードリセット カスタマイズ](https://readouble.com/laravel/5.6/ja/passwords.html#password-customization)



# メール送信について
メール送信については私はMailgunを利用しました。
[参考の記事](https://www.ritolab.com/entry/39)を元に、下記の手順でMail送信が出来る様になりました。
1.「お名前.com」でドメインの購入
2.Mailgunでドメインの登録
3.「お名前.com」でDNSレコード設定



# ルーティングの設定
[前回書いた記事](https://qiita.com/maejima_f/items/e153c097e2912d2d75c1)を元にweb.phpを編集します。



```PHP
Route::group(['prefix' => 'admin'], function(){


    // ・・・省略・・・

    // Password Reset Routes...
    Route::get('password/reset', 'Admin\Auth\ForgotPasswordController@showLinkRequestForm')->name('admin_password_request');
    Route::post('password/email', 'Admin\Auth\ForgotPasswordController@sendResetLinkEmail')->name('admin_password_email');
    Route::get('password/reset/{token}', 'Admin\Auth\ResetPasswordController@showResetForm')->name('admin_password_reset');
    Route::post('password/reset', 'Admin\Auth\ResetPasswordController@reset')->name('admin_password_reset_post');

    Route::get('home', 'Admin\HomeController@index')->name('admin_home');
});

```



# Notificationの作成

通知クラスの作成を行います。


```shell-session
[root@87c2be02241a shop]# php artisan make:notification OriginalPasswordReset
Notification created successfully.
```

「/app/Notifications/OriginalPasswordReset.php」が作成されます。


「OriginalPasswordReset.php」を編集します。


「ResetPassword」の宣言とコンストラクタにトークンを追記します。

```PHP
use Illuminate\Auth\Notifications\ResetPassword;
```

```PHP
/**
 * Create a new notification instance.
 *
 * @param string $token
 * @return void
 */
public function __construct($token)
{
    $this->token = $token;
}
```

toMailメソッドを下記の通りに編集します。
url()メソッド内のパラメーターはメールに記載されるリンクのURLになります。

```PHP
/**
 * Get the mail representation of the notification.
 *
 * @param  mixed  $notifiable
 * @return \Illuminate\Notifications\Messages\MailMessage
 */
public function toMail($notifiable)
{
    return (new MailMessage)
                ->subject(__('Reset Password'))
                ->view('emails.password_reset')
                ->action(__('Reset Password'), url('admin/password/reset', $this->token));
}
```

メールのテンプレートは上記に指定した通りに「/resources/views/emails/password_reset.blade.php」に記載された内容が反映される為、[参考](https://qiita.com/sutara79/items/0ea48847f5565aacceea)通りに編集します。



# Modelの設定

前回の記事にて作成したAdmin.phpを編集します。

宣言を追加します。

```PHP
use App\Notifications\OriginalPasswordReset;
use Illuminate\Support\Facades\Password;
```

ブローカーの取得処理と通知の送信処理を追記します。

```PHP
/**
 *パスワードリセットに使われるブローカの取得
*
* @return PasswordBroker
*/
protected function broker()
{
    return Password::broker('admin');
}

/**
 * パスワードリセット通知の送信
 *
 * @param  string  $token
 * @return void
 */
public function sendPasswordResetNotification($token)
{
    $this->notify(new OriginalPasswordReset($token));
}
```


# Viewの設定

デフォルトのAuthファイルをコピペして作成された、下記のファイルを編集します
「/resources/views/admin/passwords/email.blade.php」
「/resources/views/admin/passwords/reset.blade.php」


viewファイルはフォームアクションのrouteのnameを変更しているだけです。


email.blade.php

```PHP
-action="{{ route('password.email') }}"
+action="{{ route('admin_password_email') }}"
```

reset.blade.php

```PHP
-action="{{ route('password.request') }}"
+action="{{ route('admin_password_reset_post') }}"
```

継承元も変更します。

対象:
email.blade.php
reset.blade.php

```PHP
-@extends('layouts.app')
+@extends('layouts.admin')
```


# Controllerの設定


「ForgotPasswordController.php」、「ResetPasswordController.php」を編集します。
コンストラクタで「guest:admin」を指定し、guardメソッドで「admin」を指定する必要があります。
また、ブローカー取得処理にて「admin」を指定する必要があります。


「/app/Http/Controllers/Admin/Auth/ForgotPasswordController.php」
下記の宣言が必要です。

```PHP
use Illuminate\Support\Facades\Password;
```


```PHP
<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
use Illuminate\Support\Facades\Password;

class ForgotPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset emails and
    | includes a trait which assists in sending these notifications from
    | your application to your users. Feel free to explore this trait.
    |
    */

    use SendsPasswordResetEmails;

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest:admin');
    }

    public function guard()
    {
        return Auth::guard('admin');
    }

    /**
     * Display the form to request a password reset link.
     *
     * @return \Illuminate\Http\Response
     */
    public function showLinkRequestForm()
    {
        return view('admin.passwords.email');
    }

    /**
     *パスワードリセットに使われるブローカの取得
    *
    * @return PasswordBroker
    */
    protected function broker()
    {
        return Password::broker('admin');
    }

}
```


「/app/Http/Controllers/Admin/Auth/ResetPasswordController.php」
下記の3つの宣言が必要です。

```PHP
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;
```
パスワードリセット後のリダイレクト先を「/admin/home」に指定します。
パスワード変更メールのリンクを叩いた時に適切なviewが表示される様にshowResetForm()をこのファイル内で記述してviewファイルを指定する必要があります。

```PHP
<?php

namespace App\Http\Controllers\Admin\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ResetsPasswords;
use Illuminate\Support\Facades\Password;
use Illuminate\Support\Facades\Auth;
use Illuminate\Http\Request;

class ResetPasswordController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Password Reset Controller
    |--------------------------------------------------------------------------
    |
    | This controller is responsible for handling password reset requests
    | and uses a simple trait to include this behavior. You're free to
    | explore this trait and override any methods you wish to tweak.
    |
    */

    use ResetsPasswords;

    /**
     * Where to redirect users after resetting their password.
     *
     * @var string
     */
    protected $redirectTo = '/admin/home';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest:admin');
    }

    public function guard()
    {
        return Auth::guard('admin');
    }

    /**
     *パスワードリセットに使われるブローカの取得
    *
    * @return PasswordBroker
    */
    protected function broker()
    {
        return Password::broker('admin');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function showResetForm(Request $request, $token = null)
    {
        return view('admin.passwords.reset')->with(
            ['token' => $token, 'email' => $request->email]
        );
    }
}
```

# パスワード変更のデモ

### メールアドレス入力画面

![スクリーンショット 2018-12-16 14.57.31.png](https://qiita-image-store.s3.amazonaws.com/0/238861/f7b42b9f-97cf-a206-31e1-dd3d99a8a81f.png)


### メール送信完了

![スクリーンショット 2018-12-16 14.57.58.png](https://qiita-image-store.s3.amazonaws.com/0/238861/d7408990-35b9-fb43-7d98-fdf15c12c388.png)

### メールの画面

![スクリーンショット 2018-12-16 15.02.35.png](https://qiita-image-store.s3.amazonaws.com/0/238861/3abd5df8-4211-2ebf-c5c8-779dfdb9162d.png)

### パスワード変更画面

![スクリーンショット 2018-12-16 15.03.38.png](https://qiita-image-store.s3.amazonaws.com/0/238861/068f6a11-de15-9c72-0b5e-19c155af6568.png)

### パスワード変更完了後、ログインしてhome画面に遷移する。

![スクリーンショット 2018-12-16 15.03.55.png](https://qiita-image-store.s3.amazonaws.com/0/238861/29136627-ff9b-24de-2c07-08366ef2d771.png)


上記の対応でusersテーブル以外でパスワードリセットが出来る様になりました！