目次
Laravelの記事一覧は下記
PHPフレームワークLaravelの使い方
Laravelバージョン
動作確認はLaravel Framework 7.19.1で行っています
前提条件
eclipseでLaravel開発環境を構築する。デバッグでブレークポイントをつけて止める。(WindowsもVagrantもdockerも)
本記事は上記が完了している前提で書かれています
プロジェクトの作成もapacheの設定も上記で行っています
LaravelでJavaScript、CSSを使う
本記事は上記が完了している前提で書かれています
npm install
を上記で完了しています
npm install
が完了している前提で書かれています
Laravelでメール送信する
上記記事でLaravelからメール送信できるようにしています
本記事はメール送信ができるようになっている前提で書かれています
Laravelでデータベースを扱う準備をする
Laravelでテーブル作成
Laravelで初期データ投入
Laravelでデータベースを操作する(Eloquent編)
本記事は上記ので作成したデータベースとレコードを使用します
認証に必要なソース生成
コマンドラインで
cd sample
composer require laravel/ui
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
または、composer.jsonを修正
‥‥
"require": {
‥‥
"laravel/tinker": "^2.0",
"laravel/ui": "^2.1"
},
‥‥
"laravel/ui": "^2.1"追加しました
コマンドラインで
cd sample
composer update
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
上記composer require laravel/ui
かcomposer update
のどちらかをしてください
コマンドラインで
php artisan ui vue --auth
eclipseプロジェクトを右クリック→リフレッシュ
/sample/app/Http/Controllers/Auth、/sample/resources/views/authに多くのファイルが現れます
/sample/database/migrations/xxxx_xx_xx_xxxxxx_create_password_resets_table.phpも現れます
/sample/routes/web.phpに2行
Auth::routes();
Route::get('/home', 'HomeController@index')->name('home');
追記されています
Model修正
(1) /sample/app/User.phpを/sample/app/Models/User.phpに移動します
/sample/app/ModelsフォルダはLaravelでデータベースを操作する(Eloquent編)で作成しました
(2) /sample/app/Models/User.php修正
namespace App;
をnamespace App\Models;
に修正
(3) /sample/config/auth.php修正
‥‥
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\Models\User::class,
],
‥‥
providers->users->modelをApp\Models\User::classに修正
(4) /sample/app/Http/Controllers/Auth/RegisterController.php修正
use App\User;
をuse App\Models\User;
に修正
(5) /sample/database/factories/UserFactory.php修正
use App\User;
をuse App\Models\User;
に修正
#JavaScript、CSSビルド実行
コマンドラインで
cd sample
npm run dev
動作確認その1
http://localhost/laravelSample/
画面右上にLOGIN、REGISTERのリンクが現れました
REGISTERをクリックし、Name、E-Mail Address、Password、Confirm Passwordを入力してRegisterボタンをクリック
MySQLでlaravel_sampleデータベースを確認してみましょう
select * from users;
レコードが入っています
右上のユーザー名プルダウンからLogoutをクリック
ログアウトできました
右上のユーザー名プルダウンからLOGINをクリック
先ほど登録したE-Mail Address、Passwordを入力し、Loginボタンをクリック
ログインできました
自動生成物の確認
先ほど実行したphp artisan ui vue --auth
で生成されたソースの中身を確認しましょう
(1) web.phpの確認
/sample/routes/web.phpに追記されたAuth::routes();
は
/sample/vendor/laravel/ui/src/AuthRouteMethods.phpのauth()メソッドの戻り値を実行します
AuthRouteMethods#authはAuthRouteMethods#resetPassword、AuthRouteMethods#confirmPassword、AuthRouteMethods#emailVerification
を状況にしたがって呼び出します
見ての通り、AuthRouteMethods.phpは認証に必要なルーティングが書かれているだけです
自動生成されたルーティングをまとめると下記になります
// ログイン
get('login', 'Auth\LoginController@showLoginForm')
post('login', 'Auth\LoginController@login');
// ログアウト
post('logout', 'Auth\LoginController@logout')
// ユーザー登録
get('register', 'Auth\RegisterController@showRegistrationForm')
post('register', 'Auth\RegisterController@register');
// パスワード再発行メール送信前の操作
get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')
post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')
// パスワード再発行メール送信後の操作
get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')
post('password/reset', 'Auth\ResetPasswordController@reset')
// 特定URLアクセス時のパスワード入力要求
get('password/confirm', 'Auth\ConfirmPasswordController@showConfirmForm')
post('password/confirm', 'Auth\ConfirmPasswordController@confirm');
// ユーザー登録後のメールアドレス確認
get('email/verify', 'Auth\VerificationController@show')
get('email/verify/{id}/{hash}', 'Auth\VerificationController@verify')
post('email/resend', 'Auth\VerificationController@resend')
get('/home', 'HomeController@index')
また、web.phpに定義しているルーティングに->middleware('auth');をつけると認証済みユーザーのみアクセスできるurlになります
例
Route::get('sample/jscss', 'SampleController@jscss')->middleware('auth');
これでhttp://localhost/laravelSample/sample/jscss
にアクセスしようとするとログイン認証を要求されます
(2) Controllerクラスの確認
上記ルーティングに書かれているコントローラークラスの中を見ると実処理はトレイトに書かれていることがわかります
各コントローラーの実処理が書かれているトレイトは/sample/vendor/laravel/ui/auth-backendに入っています
対応表です
機能 | app/Http/Controllers/Auth配下のコントローラー | vendor/laravel/ui/auth-backend配下のトレイト |
---|---|---|
特定URLアクセス時のパスワード入力要求 | ConfirmPasswordController.php | ConfirmsPasswords.php |
パスワード再発行メール送信前の操作 | ForgotPasswordController.php | SendsPasswordResetEmails.php |
ログイン、ログアウト | LoginController.php | AuthenticatesUsers.php |
ユーザー登録 | RegisterController.php | RegistersUsers.php |
パスワード再発行メール送信後の操作 | ResetPasswordController.php | ResetsPasswords.php |
ユーザー登録後のメールアドレス確認 | VerificationController.php | VerifiesEmails.php |
トレイト内の処理は読めば分かるので、紹介はすこしだけにします
・RegistersUsers.phpのregister
トレイトvendor/laravel/ui/auth-backend/RegistersUsers.phpのregisterメソッドは、app/Http/Controllers/Auth/RegisterController.phpのregisterメソッドとなります。つまり、ユーザー登録メソッドです
event(new Registered($user = $this->create($request->all())));
の$this->create($request->all())
部分でRegisterController.phpのcreateが呼ばれ、その中でUser::createが実行されます。User::createでusersテーブルにレコードがinsertされます
$this->guard()
はAuth::guard()が実行され、SessionGuardが返ってきます。$this->guard()->login($user);
でログインです
・guard
guardは認証まわりの処理が書かれたクラスです
Auth::guard()
の戻り値はvendor/laravel/framework/src/Illuminate/Auth/SessionGuard.phpです
Auth::guard()は/sample/config/auth.phpの記述に対応したguardを返します。
auth.phpのdefaults->guardの値がwebなので、auth.phpのguards->web->driverの値を取り、それがsessionなので、SessionGuardを返します。SessionGuardの$this->provider
には/sample/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.phpが入っています。これもauth.phpで設定しているためです。auth.phpのproviders->users->driverがeloquentだからです
EloquentUserProviderの$this->modelにはApp\Models\Userが入っています。これもauth.phpで設定しているためです。auth.phpのproviders->users->modelがApp\Models\User::classだからです
・event
RegistersUsersでevent()が実行されています。event関数は与えられた引数のクラス名をキーにして、app/Providers/EventServiceProvider.phpの$listenから値を取得し、その値のクラスのhandleメソッドを実行します
・ログインの時に使う認証項目
デフォルトではログインの時、E-Mail AddressとPasswordを入力することになっていますが、入力項目をE-Mail Addressでないものにすることができます。なぜE-Mail AddressになっているかというとLoginController.phpで使っているトレイトvendor/laravel/ui/auth-backend/AuthenticatesUsers.php内のusername()関数が'email'を返しているからです。LoginControllerでusernameメソッドを定義しusersテーブルの別のカラムを返すようにすれば、emailではない項目を認証に使用できるようになります
・ユーザー登録の時に使う項目
ユーザー登録時の入力項目はデフォルトではname、email、passwordですが、もっと項目を増やしたい場合、tableにカラム追加し、viewにも項目を増やし、RegisterControllerのvalidatorメソッドとcreateに増やした項目の処理を追記し、App\Models\Userの$fillableにも増やした項目を追加します
・ログイン認証回数制限
ログイン認証を何回試みることを許可するか。その回数失敗したら何分間ログインできなくするかを設定できます
LoginControllerにmaxAttemptsとdecayMinutesというプロパティを定義します
// 最大ログイン認証回数
protected $maxAttempts = 5;
// $maxAttempts回ログイン失敗したら何分ログインできなくするか
protected $decayMinutes= 1;
これらはThrottlesLoginsというトレイトで使われています。
(コントローラー)app/Http/Controllers/Auth/LoginController.php->(トレイト)vendor/laravel/ui/auth-backend/AuthenticatesUsers.php->(トレイト)vendor/laravel/ui/auth-backend/ThrottlesLogins.php
maxAttempts()関数とdecayMinutes()関数が定義されています。そこで使われます。プロパティを定義しなかった場合、デフォルトで5回、ロック1分になっていることもわかります
また、hasTooManyLoginAttemptsが認証失敗制限回数になったか判定するメソッド、sendLockoutResponseがロックがかかったことを知らせるレスポンスを返すメソッドです
(3) viewの確認
/sample/resources/views/auth配下にviewは格納されています
説明が必要な難しい内容にはなっていません
画面の見た目は必ず変えると思います
/sample/resources/views/auth配下のbladeファイルを好きなように変更してください
Authファサード
Authファサードという認証ユーザーに関する便利メソッドを利用できます
use Illuminate\Support\Facades\Auth;
// 現在認証されているユーザーの取得
$user = Auth::user();
if (Auth::check()) {
// ユーザーはログインしている
}
上記のように簡単に認証済みユーザーを取得できたり、ログイン済みかどうか判定できます
このAuthファサードですが、Authファサード実行時呼ばれるのは、vendor/laravel/framework/src/Illuminate/Auth/AuthManager.phpです。このAuthManagerにメソッドが定義されていればAuthManagerのメソッドが呼ばれ、AuthManagerに定義されていないメソッドであれば、guardのメソッドが呼ばれます
Auth::user()ならAuthManagerにuserというメソッドは無いので、SessionGuardのuserメソッドが呼ばれます。Auth::check()ならAuthManagerにcheckというメソッドは無いので、SessionGuardのcheckメソッドが呼ばれています(SessionGuardのcheckメソッドは、SessionGuardで使われているGuardHelpersトレイトで実装されてます)
Auth::guard()なら、AuthManagerに定義されているのでAuthManagerのguardメソッドが呼ばれます
AuthManager
SessionGuard
ユーザー登録時のメールアドレス確認
ユーザー登録時に入力されたメールアドレス宛に実際にメールを送信し、そのメールに記載されているリンクをクリックしてもらい、メールアドレス確認をするように改修します
SMTPサーバーの設定をしてない方は下記記事を参考に事前にしておいてください
Laravelでメール送信する
メール送信される流れは下記です
ユーザー登録時
vendor/laravel/ui/auth-backend/RegistersUsers.phpのregisterメソッド内で
event(new Registered($user = $this->create($request->all())));
が呼ばれ、app/Providers/EventServiceProvider.phpによって登録されている
SendEmailVerificationNotificationクラスのhandleメソッドが実行され
app/Models/User.phpのsendEmailVerificationNotificationメソッドが呼ばれます
これでメールが送信されます
User.phpのsendEmailVerificationNotificationメソッドで呼んでいる$this->notify
はメール送信を実行するメソッドです。notifyメソッド定義場所は下記です
User.php->(トレイト)vendor/laravel/framework/src/Illuminate/Notifications/Notifiable.php->(トレイト)vendor/laravel/framework/src/Illuminate/Notifications/RoutesNotifications.php
$this->notify
の中では
vendor/laravel/framework/src/Illuminate/Notifications/ChannelManager.phpのsendを実行してメール送信しています
ではユーザー登録時メール送信するために必要なものを作っていきます
(1) メール本文の作成
/sample/resources/views/sample/registerUser.blade.phpファイル作成
<html>
<body>
<a href="{{$url}}">メールアドレスの確認</a>
</body>
</html>
(2) 通知クラスの作成
/sample/app/Notificationsフォルダ作成
/sample/app/Notifications/RegisterUser.phpファイル作成
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
use Illuminate\Auth\Notifications\VerifyEmail;
class RegisterUser extends VerifyEmail
{
use Queueable;
public function toMail($notifiable)
{
$verificationUrl = $this->verificationUrl($notifiable);
return (new MailMessage)
->subject('ユーザー登録')
->view('sample.registerUser', ['url' => $verificationUrl]);
}
}
(3) Modelの修正
/sample/app/Models/User.php修正
‥‥
use App\Notifications\RegisterUser;
‥‥
class User extends Authenticatable implements MustVerifyEmail
‥‥
public function sendEmailVerificationNotification()
{
$this->notify(new RegisterUser());
}
‥‥
use文追記
implements MustVerifyEmail追記
sendPasswordResetNotificationメソッド追加
これでvendor/laravel/framework/src/Illuminate/Auth/Listeners/SendEmailVerificationNotification.phpのhandleメソッド内のif文がtrueになります
(4) ルーティング修正
/sample/routes/web.php修正
‥
/* Auth::routes(); */
Auth::routes(['verify' => true]);
‥
Auth::routes()に引数['verify' => true]を渡す
これによって、vendor/laravel/ui/src/AuthRouteMethods.phpのauthメソッド内if ($options['verify'] ?? false)がtrueになり、emailVerificationメソッド内のルーティングが有効になります
動作確認その2
http://localhost/laravelSample/
画面右上のREGISTERをクリックし、Name、E-Mail Address、Password、Confirm Passwordを入力してRegisterボタンをクリック
入力したE-Mail Address充てにメールが送信されました
そのメールにあるリンクをクリックします
MySQLでlaravel_sampleデータベースを確認してみましょう
select * from users;
email_verified_atカラムにクリックした時刻が入っています
パスワードリセットの実装
ユーザーがパスワードを忘れた場合のパスワードリセットを実装します
パスワードリセット希望時にはメール送信が行われ、そのメールに記載されているリンクからパスワード再設定画面に遷移します
メール送信される流れは下記です
パスワードリセット画面でSend Password Reset Linkボタンをクリック時
vendor/laravel/ui/auth-backend/SendsPasswordResetEmails.phpのsendResetLinkEmailメソッド内の$this->broker()でvendor/laravel/framework/src/Illuminate/Auth/Passwords/PasswordBroker.phpを取得し、PasswordBrokerのsendResetLinkを実行します
PasswordBrokerのsendResetLink内で
app/Models/User.phpのsendPasswordResetNotificationメソッドが呼ばれます
これでメールが送信されます
ではそれを実行するために必要なものを作っていきます
(1) password_resetsテーブルの作成
先ほどphp artisan ui vue --auth
をしたときに
/sample/database/migrations/xxxx_xx_xx_xxxxxx_create_password_resets_table.php
ができています
これをデータベースに流し込みます
コマンドラインで
cd sample
php artisan migrate
xdebugの設定をしているとeclipseが実行していいですかというプロンプトを出すのでOKを押します
MySQLでlaravel_sampleデータベースを確認してみましょう
desc password_resets;
password_resetsテーブルができました
(2) メール本文の作成
/sample/resources/views/sample/resetPassword.blade.phpファイル作成
<html>
<body>
<a href="{{$url}}">パスワードリセット</a>
<div>このリンクは{{$limit}}分後に期限切れになります</div>
</body>
</html>
(2) 通知クラスの作成
/sample/app/Notifications/ResetPassword.phpファイル作成
<?php
namespace App\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class ResetPassword extends Notification
{
use Queueable;
public $token;
public function __construct($token)
{
$this->token = $token;
}
public function via($notifiable)
{
return ['mail'];
}
public function toMail($notifiable)
{
$url = url(route('password.reset', [
'token' => $this->token,
'email' => $notifiable->getEmailForPasswordReset(),
], false));
return (new MailMessage)
->subject('パスワードリセット')
->view('sample.resetPassword', ['url' => $url, 'limit' => config('auth.passwords.'.config('auth.defaults.passwords').'.expire')]);
}
public function toArray($notifiable)
{
return [];
}
}
(3) Modelの修正
/sample/app/Models/User.php修正
‥‥
use App\Notifications\ResetPassword;
‥‥
public function sendPasswordResetNotification($token)
{
$this->notify(new ResetPassword($token));
}
‥‥
use文追記
sendPasswordResetNotificationメソッド追加
動作確認その3
http://localhost/laravelSample/
画面右上のLOGINをクリックし、Forgot Your Password?リンクをクリック
E-Mail Addressを入力し、Send Password Reset Linkボタンをクリック
入力したE-Mail Address充てにメールが送信されました
そのメールにあるリンクをクリックします
Passwordを再設定する画面に遷移します