Laravel開発、ユーザー情報を編集する【3】メールアドレスを変更する
ユーザー情報編集について、残るはメールアドレスの編集です。
以前の記事でも触れましたが、単純に変更するだけであれば既に出来ています。
しかし、新規登録やパスワードリセット時にメール送付による認証をしているので、ユーザー情報編集のメールアドレス変更についても対応させていきたいです。
前回の記事はこちら。
今回の目的
メールアドレス変更時に新メールアドレス宛にメールを送付し、使用できるメールアドレスであることを確認した上で変更させる
なぜやるか
ユーザー新規登録・パスワードリセット時にメール送付による確認を実装しており、メールアドレス変更にも適用させるため。
やりたいこと
メールアドレス変更時にメールを送付したい
やったこと
メール送付の手順の詳細を考える
ユーザー編集コードを見直す
メールを送付する
新メールアドレスを一時保存する
トークンを発行する
メールフォーマットを作成する
同一メールは処理しない
実施内容
動作させるための手順を確認する
実装の手順についてこちらを参考にさせて頂きました、ありがとうございます。
まずどういう動作をさせて実装するか。具体的な手順をあげてみました。
- フォームにアクセスする
- 新メールアドレスを入力
- フォームボタン押下
- メール照合用トークン生成
- 新メールアドレス情報を一端保存
- メール送付
- メールURLからアクセス
- メールURLのトークンを照合
- 保存したメールアドレスを実際のDBに上書
- 一時保存データ削除
- 変更完了通知
メールアドレスが入力されると、一端仮のDBへデータを保存しておき、照合用のトークンを生成してメールを送付。
メールから照合用のURLにアクセスされると仮DBに保存しているメールアドレスをユーザーのメールアドレスとして登録させる…といった具合です。
この手順で実装してみます。
ユーザー編集を見直す
前回までに作成したユーザー編集コードについて見直しをする必要が出てきたため、変更します。
前回のフォームでは、編集アクションを1箇所で動作させていました。
同じフォーマットで同じ更新手順を実施していたので、この時は問題ありませんでした。
しかし、メールアドレスに関しては仮DBへの保存やメール送付などの処理が必要となり、そもそも動作が全く異なるので別の物として作成したほうが作りやすく、結果としてコードの可読性も良くなると考えました。
となると、全体的な見直しが必要です。
ビューを見直す
同じアクション・同じ送信メソッド・ページによる分類という方法でeditページを使い分ける方法で実装しましたが、このままメールアドレス送信を実装するとなると、下記の場所に変更が生じている状況となっています。
# ~/resources/views/user/edit.blade.php
フォームの冒頭部分です、処理先が異なるのでアクションが変更になります。
他にもデータの更新をするわけではないので、PUT処理も不要です。
※この記述があるまま実装しようとしてはまってました。PUTがあることでupdate処理となっており、メールアドレス処理を開始してくれない状態となりました。
これだけ内容が変わると1フォームでif,if,if…は見栄えがよくないです。メール専用の新フォームを作成します。
# ~/resources/views/user/email.blade.php
editビューを参考にメールアドレス部分のみを新たに作成しました。
ビュー作成に伴うルーティング・アクション設定
ビューファイルで設定していたアクションに対応するアクションとルーティングが必要になるので、追加します。
まずルーティングを設定します。
# ~/routes/web.php
メールアドレス変更用としてルートを作成しました。ビュー表示・メール送付用・認証用の3つのルートを作成しています。
続いて、コントローラーのアクションを設定します。
# ~/app/Http/Controllers/UserController.php
まず、動作を確認する為の処理をいれています。
バリデーションは前回作成していたので流用し、まずは入力された情報とユーザー情報を出力できるようにしました。
これで、メールアドレス変更専用のフォームとコントローラー処理ができる状態となりました。
メール送付による認証を実装する
ここから先程のコントローラーに設定を追記して、メール送付による認証を行い、メールアドレスを変更するという内容を実装していきます。
メール送付を実装する
新規登録やパスワードリセットでメール送付する機能はすでに実装していますが、元となるメール送信設定以外はAuth機能内で動作しているようです。
そこで、個別にメール送信する方法を調べました。
こちらを参考にさせて頂きました、ありがとうございます。
この中からメール送付の記述を使用します。まずは変数だけ調整してそのまま実装。
# ~/app/Http/Controllers/UserController.php
Mail::send()で値を引き渡すことでメールが送付できます。
メール送付の設定は以前設定したもので動作しました。
第一引数でメールフォーマットを指定しますが、新規登録等で使用していたメールフォーマットではうまく動作しませんでした。
フォーマット上に設定されている変数がこの状態だと動作していなかったようです。
まず送信することを目指すため、メールフォーマットは後回しとし、仮フォーマットとしてindexページを指定しています。
この状態でメールが送付され、受け取ることはできました。
メールアドレス変更情報を保存する
この状態で使用できる変数としては$userです。現状のユーザーの情報を引き渡し、そこからメールアドレスを参照してメールを送付しています。
ですが、このままではAuth::user()のメールアドレス…つまり現在登録中のメールアドレス宛に送付しています。
今回作成するのは、メールアドレス変更時の認証となるので、新しいメールアドレス宛に送付する必要があります。
検討した作成手順では、新メールアドレスを一端保存してメール送付…という流れです。
一時保存DBを新規作成して、新メールアドレスを保存した情報を引き渡してやれば、必要な情報をメールに追加して使えそうです。
というわけで、データを保存する新たなテーブルを作成します。
コマンドでchangeEmailテーブルを作成します。
$ php artisan make:migration create_changeEmail_table
# ~/database/migrations/xxxx_create_change_email_table.php
新しいメールアドレスと照合用のトークンを保存するカラムを設定しました。
マイグレーションファイルを実装してテーブルを作成しておきます。
コントローラー上でデータを保存する設定を追加します。
# ~/app/Http/Controllers/UserController.php
細々した設定がまだ入っていませんが、ベースとなるものを作成しました。
新しいDBにデータ保存し、メールを送付しています。
$update_tokenで照合用の文字列を作成しています。この情報を送付し、DB登録トークンと一致していることを確認することで、認証する形とします。
これで、トークン発行して、新メールアドレスと共にDBに保存するところまで完了です。
メールフォーマットが適当なので、送付メール内には照合先のURLは表示されない状態となっています。
トークン認証を実装する
次に認証機能を実装します。
認証の流れとしては
- メールURLからアクセス
- メールURLのトークンを照合
- 保存したメールアドレスを実際のDBに上書
- 一時保存データ削除
- 変更完了通知
こういった流れで考えていました。
メールにURLはまだ記載されていない状態ですが、照合する手順を先に実装します。
# ~/app/Http/Controllers/UserController.php
URLはコメントアウトされている形式で作成する予定です。
今回は直接URLを指定することで、動作確認しました。
アクセス後は、URLからトークンを取り出して一時保存DBと照合しています。
照合OKであれば、メールアドレスをユーザーDBへ上書し、一時保存DBの内容を消去するという形にしました。
以上で、メールアドレス変更の骨組みは完成です。
メールフォーマットを作る
あとは、メールのフォーマットを用意して、変更用URLが引き渡せると、一連の動作を完結させることができそうです。
# ~/resources/views/email/change_email.blade.php
URLを引き渡した簡単なメールフォームを作成しました。
# ~/app/Http/Controllers/UserController.php
フォーマットを適用しました。
後は実際にメールアドレス変更をして、送付メールを確認します。
# メール
フォーマットを元にして新しいメールアドレス確認用のURLを送付できるようになりました。
あとは、このアドレスをクリックすることで登録完了です。登録処理は先に完成させていたので、これで登録が完了します。
これで新メールアドレス宛てにメールを送付してアドレス確認後に登録する処理が完了しました。
その他細かな調整を実施する
同じメールアドレスの確認処理
今のままでは、同じメールアドレスに変更した…としても、変更処理されてしまします。
そもそも同じメールアドレスであれば処理する必要はありません。
同一メールアドレスはエラーとします。
# ~/app/Http/Controllers/UserController.php
userテーブル情報とフォーム送信されたメールアドレスを照合し、同じであればバリデーターを使用してエラーメッセージを返すことにしました。
以上でユーザー情報編集については完了です。
細々した問題はまだ残っていますが、最低限の編集機能としては問題ないでしょう。
次は、ユーザー登録と編集が完了したので、削除機能を実装します。