Laravelのユーザー登録を入力・確認・完了の３画面に分けた際のメモ

ユーザー登録画面を入力・確認・完了の３画面に分割する要件があり、Laravelで実装した際のメモになります。（あまりLaravelに慣れていないため、あまり綺麗なコードではないかもしれませんが、ご了承いただければと思います。）

ユーザー登録のルーティングは以下のようにしてみました。

```php:routes/web.php
Route::get('register', 'Auth\RegisterController@showRegistrationForm')->name('user.resister_show');
Route::post('register', 'Auth\RegisterController@post')->name('user.resister_post');
Route::get('register/confirm', 'Auth\RegisterController@confirm')->name('user.register_confirm');
Route::post('register/confirm', 'Auth\RegisterController@register')->name('user.resister_resister');
Route::get('register/complete', 'Auth\RegisterController@complete')->name('user.register_complete');
```

ユーザー登録後に自動的にログインさせるために、登録処理後にguardでログインしていますが、そのままログイン処理を実施してしまうと、guestミドルウェアの影響で完了画面が表示されないため、completeではguestミドルウェアを無効にしています。

```app/Http/Controllers/Auth/RegisterController.php
<?php
namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use App\Providers\RouteServiceProvider;
use App\User;
use Illuminate\Auth\Events\Registered;
use Illuminate\Foundation\Auth\RegistersUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;

class RegisterController extends Controller
{
    private $form_show = 'Auth\RegisterController@showRegistrationForm';
    private $form_confirm = 'Auth\RegisterController@confirm';
    private $form_complete = 'Auth\RegisterController@complete';

    private $formItems = ["name", "email", "password"];


    use RegistersUsers;

    protected $redirectTo = RouteServiceProvider::HOME;

    public function __construct()
    {
        // ユーザー登録後、ログインをした状態にして、完了画面を表示するため、completeではguestミドルウェアを無効にする
        $this->middleware('guest', ['except' => 'complete']);
    }

    protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => ['required', 'string', 'min:8', 'max:16', 'unique:users'],
            'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
            'password' => ['required', 'string', 'min:8', 'max:16'],
        ]);
    }

    protected function create(array $data)
    {
        return User::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => Hash::make($data['password']),
        ]);
    }

    /*
     * 入力から確認へ遷移する際の処理
     */
    function post(Request $request)
    {
        $this->validator($request->all())->validate();

        $input = $request->only($this->formItems);

        //セッションに書き込む
        $request->session()->put("form_input", $input);

        return redirect()->action($this->form_confirm);
    }

    /**
     * 登録処理
     *
     * @param \Illuminate\Http\Request $request
     * @return \Illuminate\Http\Response
     */
    public function register(Request $request)
    {
        //セッションから値を取り出す
        $input = $request->session()->get("form_input");

        // 戻るボタン
        if ($request->has("back")) {
            return redirect()->action($this->form_show)
                ->withInput($input);
        }

        //セッションに値が無い時はフォームに戻る
        if (!$input) {
            return redirect()->action($this->form_show);
        }

        $this->validator($request->all())->validate();

        event(new Registered($user = $this->create($request->all())));

        //セッションを空にする
        $request->session()->forget("form_input");

        // 登録データーでログイン
        $this->guard()->login($user, true);

        return $this->registered($request, $user)
            ?  : redirect($this->redirectPath());
    }

    /*
     * 登録完了後
     */
    function registered(Request $request, $user)
    {
        return redirect()->action($this->form_complete);
    }

    /**
     * 会員登録入力フォーム出力
     *
     * @return \Illuminate\Http\Response
     */
    public function showRegistrationForm()
    {
        return view('auth.register.register');
    }

    /*
     * 確認画面出力
     */
    public function confirm(Request $request)
    {
        //セッションから値を取り出す
        $input = $request->session()->get("form_input");

        //セッションに値が無い時はフォームに戻る
        if (!$input) {
            return redirect()->action("Auth\RegisterController");
        }

        return view('auth.register.confirm', ["input" => $input]);
    }

    /*
     * 完了画面出力
     */
    public function complete()
    {
        return view('auth.register.complete');
    }

}

```

テンプレートについては、入力、確認、完了の3画面分用意することで、とりあえず動作しました。

```/resources/views/auth/register/register.blade.php
@include('error_card_list')

<div class="card-text">
   <form method="POST" action="{{ route('user.resister_post') }}">
       @csrf
       <div class="md-form">
           <label for="name">ユーザー名</label>
           <input class="form-control" type="text" id="name" name="name" required value="{{ old('name') }}">
       </div>

       <div class="md-form">
           <label for="name">メールアドレス</label>
           <input class="form-control" type="text" id="email" name="email" required value="{{ old('email') }}">
       </div>

       <div class="md-form">
           <label for="password">パスワード</label>
           <input class="form-control" type="text" id="password" name="password" required value="{{ old('password') }}">
       </div>
       <button class="btn btn-block blue-gradient mt-2 mb-2" type="submit">新規登録</button>
   </form>
</div>
```

```/resources/views/auth/register/confirm.blade.php
<div class="card-text">
    <form method="POST" action="{{ route('user.resister_resister') }}">
        @csrf
        <div class="md-form">
            <label for="name">ユーザー名</label>
            {{ $input["name"] }}
            <input class="form-control" type="hidden" id="name" name="name" required value="{{ $input["name"] }}">
        </div>

        <div class="md-form">
            <label for="name">メールアドレス</label>
            {{ $input["email] }}
            <input class="form-control" type="hidden" id="email" name="email" required value="{{ $input["email"] }}">
        </div>

        <div class="md-form">
            <label for="password">パスワード</label>
            {{ $input["password"] }}
            <input class="form-control" type="hidden" id="password" name="password" required value="{{ $input["password"] }}">
        </div>

        <button class="btn btn-block blue-gradient mt-2 mb-2" type="submit" name="back"">戻って変更する</button>
        <button class="btn btn-block blue-gradient mt-2 mb-2" type="submit">確認して登録する</button>
    </form>
</div>
```

```/resources/views/auth/register/complete.blade.php
<div class="card-body pt-0 pb-2">
    <h3 class="h4 card-title">
        ご登録ありがとうございました！
    </h3>
</div>
```


以上になります。