【Laravel8】ユーザーの新規登録を制限する
前に【Laravel】ユーザーの新規登録を制限するという記事を書きましたが、Laravel8でも同じ実装が必要になったので、調べてみた。内容的には、一般ユーザーに自由にユーザー登録をさせずに、特定のユーザーにのみ登録をさせるための方法です。Auth関連のルーティングをカスタマイズして、ユーザーの新規登録を制限します。
前提
Laravel8
Jetstreamによるログイン機能を実装している。
新規登録を完全に無効にしたい場合
ユーザーの新規登録を完全に禁止にして登録させたくない場合です。
「config/fortify.php」の以下の箇所で、新規登録の部分をコメントアウト(無効に)するだけです。
'features' => [
//Features::registration(), // 新規登録
Features::resetPasswords(), // パスワードリセット
Features::emailVerification(), // メール認証
Features::updateProfileInformation(), // 登録情報の更新
Features::updatePasswords(), // パスワードの更新
Features::twoFactorAuthentication([ // 2段階認証
'confirmPassword' => true,
]),
],
各ページの新規登録ボタンはこれによって表示されなくなります。
config内を編集した場合は、「php artisan config:clear」を忘れずに。
新規登録を簡易的に制限したい場合
一般ユーザーには新規登録はさせたくないけど、特定のユーザーのみ登録ができるようにする方法です。
今回は、新規登録の機能は有効のままで、「新規登録ボタンの削除」と「URLの変更」で、ユーザーの新規登録を制限します。URLを知らないと新規登録ができないという少しゆるめの制限です。しっかり制限したい場合は、別の方法をとってください。
新規登録ボタンの削除
まず、新規登録ページへのリンクをすべて削除します。
Auth関連のファイル
「resources/views/auth/login.blade.php」
「resources/views/layouts/app.blade.php」
上記ファイル内の新規登録ボタンの削除。
その他、新規登録ページへのリンクがある場合は、すべて削除します。
URLの変更
新規登録ボタンを削除すれば、登録ページへは行けなくなりますが、デフォルトのルーティングのままだと、「○○/register」というURLなので、推測されてアクセスされてしまうので、URLを変更します。
ルーティングのカスタマイズ
Laravel7までは、Auth関連のルーティングは以下の一行で実装されていました。
routes/web.php
Auth::routes();
Laravel8からは、Auth関連のルーティングはvendor内「vendor/laravel/fortify/routes/routes.php」に入ってしまいました。これはpublishして外へ出すことができないとのこと。
なので、Auth関連のルーティングを無効にしてから、「routes/web.php」にすべてのルーティングを設定し直す必要があります。
Auth関連のルーティングを無効
Auth関連のルーティングを無効にするには、「app/Providers/FortifyServiceProvider.php」の以下の箇所を編集します。
public function register()
{
Fortify::ignoreRoutes(); // ←これを追記
}
Auth関連のルーティングをし直す
「vendor/laravel/fortify/routes/routes.php」に書かれたルーティングをすべて「routes/web.php」に追記します。
追記するルーティング部分は以下の通り。(結構な量ですが)
Route::group(['middleware' => config('fortify.middleware', ['web'])], function () {
$enableViews = config('fortify.views', true);
// Authentication...
if ($enableViews) {
Route::get('/login', [AuthenticatedSessionController::class, 'create'])
->middleware(['guest'])
->name('login');
}
$limiter = config('fortify.limiters.login');
$twoFactorLimiter = config('fortify.limiters.two-factor');
Route::post('/login', [AuthenticatedSessionController::class, 'store'])
->middleware(array_filter([
'guest',
$limiter ? 'throttle:'.$limiter : null,
]));
Route::post('/logout', [AuthenticatedSessionController::class, 'destroy'])
->name('logout');
// Password Reset...
if (Features::enabled(Features::resetPasswords())) {
if ($enableViews) {
Route::get('/forgot-password', [PasswordResetLinkController::class, 'create'])
->middleware(['guest'])
->name('password.request');
Route::get('/reset-password/{token}', [NewPasswordController::class, 'create'])
->middleware(['guest'])
->name('password.reset');
}
Route::post('/forgot-password', [PasswordResetLinkController::class, 'store'])
->middleware(['guest'])
->name('password.email');
Route::post('/reset-password', [NewPasswordController::class, 'store'])
->middleware(['guest'])
->name('password.update');
}
// Registration...
if (Features::enabled(Features::registration())) {
if ($enableViews) {
Route::get('/register', [RegisteredUserController::class, 'create'])
->middleware(['guest'])
->name('register');
}
Route::post('/register', [RegisteredUserController::class, 'store'])
->middleware(['guest']);
}
// Email Verification...
if (Features::enabled(Features::emailVerification())) {
if ($enableViews) {
Route::get('/email/verify', [EmailVerificationPromptController::class, '__invoke'])
->middleware(['auth'])
->name('verification.notice');
}
Route::get('/email/verify/{id}/{hash}', [VerifyEmailController::class, '__invoke'])
->middleware(['auth', 'signed', 'throttle:6,1'])
->name('verification.verify');
Route::post('/email/verification-notification', [EmailVerificationNotificationController::class, 'store'])
->middleware(['auth', 'throttle:6,1'])
->name('verification.send');
}
// Profile Information...
if (Features::enabled(Features::updateProfileInformation())) {
Route::put('/user/profile-information', [ProfileInformationController::class, 'update'])
->middleware(['auth'])
->name('user-profile-information.update');
}
// Passwords...
if (Features::enabled(Features::updatePasswords())) {
Route::put('/user/password', [PasswordController::class, 'update'])
->middleware(['auth'])
->name('user-password.update');
}
// Password Confirmation...
if ($enableViews) {
Route::get('/user/confirm-password', [ConfirmablePasswordController::class, 'show'])
->middleware(['auth'])
->name('password.confirm');
}
Route::get('/user/confirmed-password-status', [ConfirmedPasswordStatusController::class, 'show'])
->middleware(['auth'])
->name('password.confirmation');
Route::post('/user/confirm-password', [ConfirmablePasswordController::class, 'store'])
->middleware(['auth']);
// Two Factor Authentication...
if (Features::enabled(Features::twoFactorAuthentication())) {
if ($enableViews) {
Route::get('/two-factor-challenge', [TwoFactorAuthenticatedSessionController::class, 'create'])
->middleware(['guest'])
->name('two-factor.login');
}
Route::post('/two-factor-challenge', [TwoFactorAuthenticatedSessionController::class, 'store'])
->middleware(array_filter([
'guest',
$twoFactorLimiter ? 'throttle:'.$twoFactorLimiter : null,
]));
$twoFactorMiddleware = Features::optionEnabled(Features::twoFactorAuthentication(), 'confirmPassword')
? ['auth', 'password.confirm']
: ['auth'];
Route::post('/user/two-factor-authentication', [TwoFactorAuthenticationController::class, 'store'])
->middleware($twoFactorMiddleware);
Route::delete('/user/two-factor-authentication', [TwoFactorAuthenticationController::class, 'destroy'])
->middleware($twoFactorMiddleware);
Route::get('/user/two-factor-qr-code', [TwoFactorQrCodeController::class, 'show'])
->middleware($twoFactorMiddleware);
Route::get('/user/two-factor-recovery-codes', [RecoveryCodeController::class, 'index'])
->middleware($twoFactorMiddleware);
Route::post('/user/two-factor-recovery-codes', [RecoveryCodeController::class, 'store'])
->middleware($twoFactorMiddleware);
}
});
この新規登録のルーティングの部分を以下のようにカスタマイズします。
//新規登録(カスタムURL)
if (Features::enabled(Features::registration())) {
if ($enableViews) {
Route::get('/[ここに任意の文字列]', [RegisteredUserController::class, 'create'])
->middleware(['guest'])
->name('register');
}
Route::post('/[ここに任意の文字列]', [RegisteredUserController::class, 'store'])
->middleware(['guest']);
}
好きな文字列を設定して新規登録URLを変更します。より複雑な文字列の方が安全です。
あと、ルーティングに使われているController関連のインポートも必要です。「routes/web.php」の上の方に、以下を追記します。
use Laravel\Fortify\Features; use Laravel\Fortify\Http\Controllers\AuthenticatedSessionController; use Laravel\Fortify\Http\Controllers\ConfirmablePasswordController; use Laravel\Fortify\Http\Controllers\ConfirmedPasswordStatusController; use Laravel\Fortify\Http\Controllers\EmailVerificationNotificationController; use Laravel\Fortify\Http\Controllers\EmailVerificationPromptController; use Laravel\Fortify\Http\Controllers\NewPasswordController; use Laravel\Fortify\Http\Controllers\PasswordController; use Laravel\Fortify\Http\Controllers\PasswordResetLinkController; use Laravel\Fortify\Http\Controllers\ProfileInformationController; use Laravel\Fortify\Http\Controllers\RecoveryCodeController; use Laravel\Fortify\Http\Controllers\RegisteredUserController; use Laravel\Fortify\Http\Controllers\TwoFactorAuthenticatedSessionController; use Laravel\Fortify\Http\Controllers\TwoFactorAuthenticationController; use Laravel\Fortify\Http\Controllers\TwoFactorQrCodeController; use Laravel\Fortify\Http\Controllers\VerifyEmailController;
まとめ
以上で、一般ユーザーの新規登録の制限ができたと思います。ユーザー登録させたい特定のユーザーには、設定した文字列のURLを教えてあげれば、通常通りユーザー登録ができます。ただ、URLを知った人はすべて登録ができてしまうので、もっと厳密に制限したい場合は別の方法をとる必要があります。
-
前の記事
【Laravel】ユーザーの新規登録を制限する 2021.06.21
-
次の記事
LaravelでAWSのS3接続時のエラー(InvalidArgumentException) 2021.08.28
コメントを書く