概要
Laravel8.xとVue.js3を使用してSPAのサイトを作る際にログイン周りでいろいろ苦戦したので記事にしました。
今回はログイン、会員登録のバックエンド部分を実装します。
Laravel8,Fortify,Sanctum,Vue.js3の環境構築は前回の記事をご確認ください。
https://saunabouya.com/2022/01/27/laravel8-fortify-sanctum-vue-js3-compositon-api-1/
Laravel Fortifyではログイン周りのバックエンド部分はLaravel側で用意してくれるのでそれに合わせたルーティングをフロント側で組み込んであげればログイン認証は実装することができます。
環境構築ができたらまずはphp artisan route:list
でルーティングを確認してみましょう。
api/login | Laravel\Fortify\Http\Controllers\AuthenticatedSessionController@store
api/register | Laravel\Fortify\Http\Controllers\RegisteredUserController@store
Laravel Fortifyのlogin処理はAuthenticatedSessionControllerのstoreアクションが担っています
storeアクションを見るとログイン処理に成功するとLoginResponseにreturnしていることがわかります。
このLoginResponseを拡張してカスタマイズしていきます。
LoginResponse.phpを作成
app/Http/ResponsesにLoginResponse.phpを作成します。
内容は/vendor/laravel/fortify/src/Http/Responses/LoginResponse.phpをコピペしてreturnする内容を変更します。
<?php
namespace App\Http\Responses;
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract;
use Illuminate\Support\Facades\Auth;
use Laravel\Fortify\Fortify;
use Illuminate\Validation\ValidationException;
class LoginResponse implements LoginResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
$user = Auth::user();
return $request->wantsJson()
? response()->json($user, 200) //ログイン後user情報とレスポンスステータスOKを渡す
: redirect()->intended(Fortify::redirects('login'));
}
}
RegisterResponse.phpを作成
LoginResponseと同様にapp/Http/ResponsesにRegisterResponse.phpを作成します。
register処理はRegisteredUserControllerのstoreアクションが担っています
登録処理に成功するとRegisterResponseにreturnしていますので
このRegisterResponseを拡張してカスタマイズしていきます。
ユーザー登録のバリデーションに関してはApp/Actions/Fortify/CreateNewUser.phpに記載されていますので、カスタマイズする際はそちらを参照ください。
<?php
namespace App\Http\Responses;
use Illuminate\Http\JsonResponse;
use Laravel\Fortify\Contracts\RegisterResponse as RegisterResponseContract;
use Illuminate\Support\Facades\Auth;
class RegisterResponse implements RegisterResponseContract
{
/**
* Create an HTTP response that represents the object.
*
* @param \Illuminate\Http\Request $request
* @return \Symfony\Component\HttpFoundation\Response
*/
public function toResponse($request)
{
$user = Auth::user();
return $request->wantsJson()
? new JsonResponse($user, 201) //登録後user情報とレスポンスステータスCreatedを渡す
: redirect('/');
}
}
FortifyServiceProviderを編集
FortifyServiceProviderを下記のように編集
<?php
namespace App\Providers;
use App\Actions\Fortify\CreateNewUser;
use App\Actions\Fortify\ResetUserPassword;
use App\Actions\Fortify\UpdateUserPassword;
use App\Actions\Fortify\UpdateUserProfileInformation;
use Illuminate\Cache\RateLimiting\Limit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\RateLimiter;
use Illuminate\Support\ServiceProvider;
use Laravel\Fortify\Fortify;
use Laravel\Fortify\Contracts\LoginResponse as LoginResponseContract; //追記
use App\Http\Responses\LoginResponse; //追記
use Laravel\Fortify\Contracts\RegisterResponse as RegisterResponseContract; //追記
use App\Http\Responses\RegisterResponse; //追記
class FortifyServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Fortify::createUsersUsing(CreateNewUser::class);
Fortify::updateUserProfileInformationUsing(UpdateUserProfileInformation::class);
Fortify::updateUserPasswordsUsing(UpdateUserPassword::class);
Fortify::resetUserPasswordsUsing(ResetUserPassword::class);
RateLimiter::for('login', function (Request $request) {
$email = (string) $request->email;
return Limit::perMinute(5)->by($email.$request->ip());
});
RateLimiter::for('two-factor', function (Request $request) {
return Limit::perMinute(5)->by($request->session()->get('login.id'));
});
$this->app->singleton(LoginResponseContract::class, LoginResponse::class); //追記
$this->app->singleton(RegisterResponseContract::class, RegisterResponse::class); //追記
}
}
これでバックエンド部分は完成です。次回はフロント部分を作成します。