同じサイトシステムでも、利用者側と管理者側で別々に利用することがあります。
その場合、認証方法も別々に構築することが多いと思います。
Laravel にも、同じようなことが実現できます。
下記の参考サイトでは、非常に丁寧に詳しく解説されています。
この記事に説明されている通りに構築、実装していくことで、確実にマルチログインを実現することができると思います。
しかしながら、細かい部分の記載がなかったり、Laravel10の説明ではなかったので、ざっくりと当記事で、補足的に解説していきたいと思います。
Laravel で、マルチログインを実装する場合には、ぜひ、参考にしていただければと思います。
参考サイト
Laravel9のBreezeで、ユーザー登録・ログインを実装する
https://specially198.com/implement-user-registration-and-login-with-breeze-of-laravel9/
Laravel9のBreezeで、マルチログインを実装する
https://specially198.com/implement-multi-login-with-laravel9-breeze/
プロジェクトの作成
1 |
composer create-project "laravel/laravel=10.*" |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 |
Creating a "laravel/laravel=10.*" project at "./laravel" Installing laravel/laravel (v10.3.2) - Downloading laravel/laravel (v10.3.2) - Installing laravel/laravel (v10.3.2): Extracting archive Created project in /home/hogehoge/demo.net/laravel > @php -r "file_exists('.env') || copy('.env.example', '.env');" Loading composer repositories with package information Updating dependencies Lock file operations: 111 installs, 0 updates, 0 removals - Locking brick/math (0.11.0) - Locking carbonphp/carbon-doctrine-types (2.1.0) - Locking dflydev/dot-access-data (v3.0.2) - Locking doctrine/inflector (2.0.9) - Locking doctrine/lexer (3.0.1) - Locking dragonmantank/cron-expression (v3.3.3) - Locking egulias/email-validator (4.0.2) - Locking fakerphp/faker (v1.23.1) - Locking filp/whoops (2.15.4) - Locking fruitcake/php-cors (v1.3.0) - Locking graham-campbell/result-type (v1.1.2) - Locking guzzlehttp/guzzle (7.8.1) - Locking guzzlehttp/promises (2.0.2) - Locking guzzlehttp/psr7 (2.6.2) - Locking guzzlehttp/uri-template (v1.0.3) - Locking hamcrest/hamcrest-php (v2.0.1) - Locking laravel/framework (v10.43.0) - Locking laravel/pint (v1.13.10) - Locking laravel/prompts (v0.1.15) - Locking laravel/sail (v1.27.3) - Locking laravel/sanctum (v3.3.3) - Locking laravel/serializable-closure (v1.3.3) - Locking laravel/tinker (v2.9.0) - Locking league/commonmark (2.4.2) - Locking league/config (v1.2.0) - Locking league/flysystem (3.24.0) - Locking league/flysystem-local (3.23.1) - Locking league/mime-type-detection (1.15.0) - Locking mockery/mockery (1.6.7) - Locking monolog/monolog (3.5.0) - Locking myclabs/deep-copy (1.11.1) - Locking nesbot/carbon (2.72.3) - Locking nette/schema (v1.3.0) - Locking nette/utils (v4.0.4) - Locking nikic/php-parser (v5.0.0) - Locking nunomaduro/collision (v7.10.0) - Locking nunomaduro/termwind (v1.15.1) - Locking phar-io/manifest (2.0.3) - Locking phar-io/version (3.2.1) - Locking phpoption/phpoption (1.9.2) - Locking phpunit/php-code-coverage (10.1.11) - Locking phpunit/php-file-iterator (4.1.0) - Locking phpunit/php-invoker (4.0.0) - Locking phpunit/php-text-template (3.0.1) - Locking phpunit/php-timer (6.0.0) - Locking phpunit/phpunit (10.5.10) - Locking psr/clock (1.0.0) - Locking psr/container (2.0.2) - Locking psr/event-dispatcher (1.0.0) - Locking psr/http-client (1.0.3) - Locking psr/http-factory (1.0.2) - Locking psr/http-message (2.0) - Locking psr/log (3.0.0) - Locking psr/simple-cache (3.0.0) - Locking psy/psysh (v0.12.0) - Locking ralouphie/getallheaders (3.0.3) - Locking ramsey/collection (2.0.0) - Locking ramsey/uuid (4.7.5) - Locking sebastian/cli-parser (2.0.0) - Locking sebastian/code-unit (2.0.0) - Locking sebastian/code-unit-reverse-lookup (3.0.0) - Locking sebastian/comparator (5.0.1) - Locking sebastian/complexity (3.2.0) - Locking sebastian/diff (5.1.0) - Locking sebastian/environment (6.0.1) - Locking sebastian/exporter (5.1.1) - Locking sebastian/global-state (6.0.1) - Locking sebastian/lines-of-code (2.0.2) - Locking sebastian/object-enumerator (5.0.0) - Locking sebastian/object-reflector (3.0.0) - Locking sebastian/recursion-context (5.0.0) - Locking sebastian/type (4.0.0) - Locking sebastian/version (4.0.1) - Locking spatie/backtrace (1.5.3) - Locking spatie/flare-client-php (1.4.4) - Locking spatie/ignition (1.12.0) - Locking spatie/laravel-ignition (2.4.1) - Locking symfony/console (v6.4.3) - Locking symfony/css-selector (v6.4.3) - Locking symfony/deprecation-contracts (v3.4.0) - Locking symfony/error-handler (v6.4.3) - Locking symfony/event-dispatcher (v6.4.3) - Locking symfony/event-dispatcher-contracts (v3.4.0) - Locking symfony/finder (v6.4.0) - Locking symfony/http-foundation (v6.4.3) - Locking symfony/http-kernel (v6.4.3) - Locking symfony/mailer (v6.4.3) - Locking symfony/mime (v6.4.3) - Locking symfony/polyfill-ctype (v1.29.0) - Locking symfony/polyfill-intl-grapheme (v1.29.0) - Locking symfony/polyfill-intl-idn (v1.29.0) - Locking symfony/polyfill-intl-normalizer (v1.29.0) - Locking symfony/polyfill-mbstring (v1.29.0) - Locking symfony/polyfill-php72 (v1.29.0) - Locking symfony/polyfill-php80 (v1.29.0) - Locking symfony/polyfill-php83 (v1.29.0) - Locking symfony/polyfill-uuid (v1.29.0) - Locking symfony/process (v6.4.3) - Locking symfony/routing (v6.4.3) - Locking symfony/service-contracts (v3.4.1) - Locking symfony/string (v6.4.3) - Locking symfony/translation (v6.4.3) - Locking symfony/translation-contracts (v3.4.1) - Locking symfony/uid (v6.4.3) - Locking symfony/var-dumper (v6.4.3) - Locking symfony/yaml (v6.4.3) - Locking theseer/tokenizer (1.2.2) - Locking tijsverkoyen/css-to-inline-styles (v2.2.7) - Locking vlucas/phpdotenv (v5.6.0) - Locking voku/portable-ascii (2.0.1) - Locking webmozart/assert (1.11.0) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 111 installs, 0 updates, 0 removals - Downloading doctrine/inflector (2.0.9) - Downloading doctrine/lexer (3.0.1) - Downloading symfony/polyfill-ctype (v1.29.0) - Downloading fakerphp/faker (v1.23.1) - Downloading symfony/polyfill-php80 (v1.29.0) - Downloading symfony/polyfill-php83 (v1.29.0) - Downloading symfony/polyfill-mbstring (v1.29.0) - Downloading symfony/http-foundation (v6.4.3) - Downloading fruitcake/php-cors (v1.3.0) - Downloading psr/http-client (1.0.3) - Downloading guzzlehttp/psr7 (2.6.2) - Downloading guzzlehttp/promises (2.0.2) - Downloading guzzlehttp/guzzle (7.8.1) - Downloading guzzlehttp/uri-template (v1.0.3) - Downloading laravel/pint (v1.13.10) - Downloading symfony/polyfill-intl-normalizer (v1.29.0) - Downloading symfony/polyfill-intl-grapheme (v1.29.0) - Downloading symfony/string (v6.4.3) - Downloading symfony/service-contracts (v3.4.1) - Downloading symfony/console (v6.4.3) - Downloading phpoption/phpoption (1.9.2) - Downloading graham-campbell/result-type (v1.1.2) - Downloading vlucas/phpdotenv (v5.6.0) - Downloading symfony/css-selector (v6.4.3) - Downloading tijsverkoyen/css-to-inline-styles (v2.2.7) - Downloading symfony/var-dumper (v6.4.3) - Downloading symfony/polyfill-uuid (v1.29.0) - Downloading symfony/uid (v6.4.3) - Downloading symfony/routing (v6.4.3) - Downloading symfony/process (v6.4.3) - Downloading symfony/polyfill-php72 (v1.29.0) - Downloading symfony/polyfill-intl-idn (v1.29.0) - Downloading symfony/mime (v6.4.3) - Downloading symfony/event-dispatcher (v6.4.3) - Downloading egulias/email-validator (4.0.2) - Downloading symfony/mailer (v6.4.3) - Downloading symfony/error-handler (v6.4.3) - Downloading symfony/http-kernel (v6.4.3) - Downloading symfony/finder (v6.4.0) - Downloading ramsey/uuid (4.7.5) - Downloading symfony/translation-contracts (v3.4.1) - Downloading symfony/translation (v6.4.3) - Downloading carbonphp/carbon-doctrine-types (2.1.0) - Downloading nesbot/carbon (2.72.3) - Downloading monolog/monolog (3.5.0) - Downloading league/mime-type-detection (1.15.0) - Downloading league/flysystem (3.24.0) - Downloading league/flysystem-local (3.23.1) - Downloading nette/utils (v4.0.4) - Downloading nette/schema (v1.3.0) - Downloading league/commonmark (2.4.2) - Downloading laravel/serializable-closure (v1.3.3) - Downloading laravel/prompts (v0.1.15) - Downloading laravel/framework (v10.43.0) - Downloading symfony/yaml (v6.4.3) - Downloading laravel/sail (v1.27.3) - Downloading laravel/sanctum (v3.3.3) - Downloading nikic/php-parser (v5.0.0) - Downloading psy/psysh (v0.12.0) - Downloading laravel/tinker (v2.9.0) - Downloading mockery/mockery (1.6.7) - Downloading filp/whoops (2.15.4) - Downloading nunomaduro/collision (v7.10.0) - Downloading sebastian/exporter (5.1.1) - Downloading sebastian/diff (5.1.0) - Downloading phpunit/php-text-template (3.0.1) - Downloading phpunit/php-file-iterator (4.1.0) - Downloading theseer/tokenizer (1.2.2) - Downloading sebastian/lines-of-code (2.0.2) - Downloading sebastian/complexity (3.2.0) - Downloading phpunit/php-code-coverage (10.1.11) - Downloading phpunit/phpunit (10.5.10) - Downloading spatie/flare-client-php (1.4.4) - Downloading spatie/ignition (1.12.0) - Downloading spatie/laravel-ignition (2.4.1) - Installing doctrine/inflector (2.0.9): Extracting archive - Installing doctrine/lexer (3.0.1): Extracting archive - Installing symfony/polyfill-ctype (v1.29.0): Extracting archive - Installing webmozart/assert (1.11.0): Extracting archive - Installing dragonmantank/cron-expression (v3.3.3): Extracting archive - Installing symfony/deprecation-contracts (v3.4.0): Extracting archive - Installing psr/container (2.0.2): Extracting archive - Installing fakerphp/faker (v1.23.1): Extracting archive - Installing symfony/polyfill-php80 (v1.29.0): Extracting archive - Installing symfony/polyfill-php83 (v1.29.0): Extracting archive - Installing symfony/polyfill-mbstring (v1.29.0): Extracting archive - Installing symfony/http-foundation (v6.4.3): Extracting archive - Installing fruitcake/php-cors (v1.3.0): Extracting archive - Installing psr/http-message (2.0): Extracting archive - Installing psr/http-client (1.0.3): Extracting archive - Installing ralouphie/getallheaders (3.0.3): Extracting archive - Installing psr/http-factory (1.0.2): Extracting archive - Installing guzzlehttp/psr7 (2.6.2): Extracting archive - Installing guzzlehttp/promises (2.0.2): Extracting archive - Installing guzzlehttp/guzzle (7.8.1): Extracting archive - Installing guzzlehttp/uri-template (v1.0.3): Extracting archive - Installing laravel/pint (v1.13.10): Extracting archive - Installing symfony/polyfill-intl-normalizer (v1.29.0): Extracting archive - Installing symfony/polyfill-intl-grapheme (v1.29.0): Extracting archive - Installing symfony/string (v6.4.3): Extracting archive - Installing symfony/service-contracts (v3.4.1): Extracting archive - Installing symfony/console (v6.4.3): Extracting archive - Installing voku/portable-ascii (2.0.1): Extracting archive - Installing phpoption/phpoption (1.9.2): Extracting archive - Installing graham-campbell/result-type (v1.1.2): Extracting archive - Installing vlucas/phpdotenv (v5.6.0): Extracting archive - Installing symfony/css-selector (v6.4.3): Extracting archive - Installing tijsverkoyen/css-to-inline-styles (v2.2.7): Extracting archive - Installing symfony/var-dumper (v6.4.3): Extracting archive - Installing symfony/polyfill-uuid (v1.29.0): Extracting archive - Installing symfony/uid (v6.4.3): Extracting archive - Installing symfony/routing (v6.4.3): Extracting archive - Installing symfony/process (v6.4.3): Extracting archive - Installing symfony/polyfill-php72 (v1.29.0): Extracting archive - Installing symfony/polyfill-intl-idn (v1.29.0): Extracting archive - Installing symfony/mime (v6.4.3): Extracting archive - Installing psr/event-dispatcher (1.0.0): Extracting archive - Installing symfony/event-dispatcher-contracts (v3.4.0): Extracting archive - Installing symfony/event-dispatcher (v6.4.3): Extracting archive - Installing psr/log (3.0.0): Extracting archive - Installing egulias/email-validator (4.0.2): Extracting archive - Installing symfony/mailer (v6.4.3): Extracting archive - Installing symfony/error-handler (v6.4.3): Extracting archive - Installing symfony/http-kernel (v6.4.3): Extracting archive - Installing symfony/finder (v6.4.0): Extracting archive - Installing ramsey/collection (2.0.0): Extracting archive - Installing brick/math (0.11.0): Extracting archive - Installing ramsey/uuid (4.7.5): Extracting archive - Installing psr/simple-cache (3.0.0): Extracting archive - Installing nunomaduro/termwind (v1.15.1): Extracting archive - Installing symfony/translation-contracts (v3.4.1): Extracting archive - Installing symfony/translation (v6.4.3): Extracting archive - Installing psr/clock (1.0.0): Extracting archive - Installing carbonphp/carbon-doctrine-types (2.1.0): Extracting archive - Installing nesbot/carbon (2.72.3): Extracting archive - Installing monolog/monolog (3.5.0): Extracting archive - Installing league/mime-type-detection (1.15.0): Extracting archive - Installing league/flysystem (3.24.0): Extracting archive - Installing league/flysystem-local (3.23.1): Extracting archive - Installing nette/utils (v4.0.4): Extracting archive - Installing nette/schema (v1.3.0): Extracting archive - Installing dflydev/dot-access-data (v3.0.2): Extracting archive - Installing league/config (v1.2.0): Extracting archive - Installing league/commonmark (2.4.2): Extracting archive - Installing laravel/serializable-closure (v1.3.3): Extracting archive - Installing laravel/prompts (v0.1.15): Extracting archive - Installing laravel/framework (v10.43.0): Extracting archive - Installing symfony/yaml (v6.4.3): Extracting archive - Installing laravel/sail (v1.27.3): Extracting archive - Installing laravel/sanctum (v3.3.3): Extracting archive - Installing nikic/php-parser (v5.0.0): Extracting archive - Installing psy/psysh (v0.12.0): Extracting archive - Installing laravel/tinker (v2.9.0): Extracting archive - Installing hamcrest/hamcrest-php (v2.0.1): Extracting archive - Installing mockery/mockery (1.6.7): Extracting archive - Installing filp/whoops (2.15.4): Extracting archive - Installing nunomaduro/collision (v7.10.0): Extracting archive - Installing sebastian/version (4.0.1): Extracting archive - Installing sebastian/type (4.0.0): Extracting archive - Installing sebastian/recursion-context (5.0.0): Extracting archive - Installing sebastian/object-reflector (3.0.0): Extracting archive - Installing sebastian/object-enumerator (5.0.0): Extracting archive - Installing sebastian/global-state (6.0.1): Extracting archive - Installing sebastian/exporter (5.1.1): Extracting archive - Installing sebastian/environment (6.0.1): Extracting archive - Installing sebastian/diff (5.1.0): Extracting archive - Installing sebastian/comparator (5.0.1): Extracting archive - Installing sebastian/code-unit (2.0.0): Extracting archive - Installing sebastian/cli-parser (2.0.0): Extracting archive - Installing phpunit/php-timer (6.0.0): Extracting archive - Installing phpunit/php-text-template (3.0.1): Extracting archive - Installing phpunit/php-invoker (4.0.0): Extracting archive - Installing phpunit/php-file-iterator (4.1.0): Extracting archive - Installing theseer/tokenizer (1.2.2): Extracting archive - Installing sebastian/lines-of-code (2.0.2): Extracting archive - Installing sebastian/complexity (3.2.0): Extracting archive - Installing sebastian/code-unit-reverse-lookup (3.0.0): Extracting archive - Installing phpunit/php-code-coverage (10.1.11): Extracting archive - Installing phar-io/version (3.2.1): Extracting archive - Installing phar-io/manifest (2.0.3): Extracting archive - Installing myclabs/deep-copy (1.11.1): Extracting archive - Installing phpunit/phpunit (10.5.10): Extracting archive - Installing spatie/backtrace (1.5.3): Extracting archive - Installing spatie/flare-client-php (1.4.4): Extracting archive - Installing spatie/ignition (1.12.0): Extracting archive - Installing spatie/laravel-ignition (2.4.1): Extracting archive 46 package suggestions were added by new dependencies, use `composer suggest` to see details. Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi INFO Discovering packages. laravel/sail ............................................................................................. DONE laravel/sanctum .......................................................................................... DONE laravel/tinker ........................................................................................... DONE nesbot/carbon ............................................................................................ DONE nunomaduro/collision ..................................................................................... DONE nunomaduro/termwind ...................................................................................... DONE spatie/laravel-ignition .................................................................................. DONE 83 packages you are using are looking for funding. Use the `composer fund` command to find out more! > @php artisan vendor:publish --tag=laravel-assets --ansi --force INFO No publishable resources for tag [laravel-assets]. No security vulnerability advisories found > @php artisan key:generate --ansi INFO Application key set successfully. |
Breezeをインストール
1 |
composer require laravel/breeze --dev |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
./composer.json has been updated Running composer update laravel/breeze Loading composer repositories with package information Updating dependencies Lock file operations: 1 install, 0 updates, 0 removals - Locking laravel/breeze (v1.28.1) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 1 install, 0 updates, 0 removals - Downloading laravel/breeze (v1.28.1) - Installing laravel/breeze (v1.28.1): Extracting archive Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi INFO Discovering packages. laravel/breeze ........................................................................................... DONE laravel/sail ............................................................................................. DONE laravel/sanctum .......................................................................................... DONE laravel/tinker ........................................................................................... DONE nesbot/carbon ............................................................................................ DONE nunomaduro/collision ..................................................................................... DONE nunomaduro/termwind ...................................................................................... DONE spatie/laravel-ignition .................................................................................. DONE 83 packages you are using are looking for funding. Use the `composer fund` command to find out more! > @php artisan vendor:publish --tag=laravel-assets --ansi --force INFO No publishable resources for tag [laravel-assets]. No security vulnerability advisories found Using version ^1.28 for laravel/breeze |
続いて、ビューやコントローラーなど各種リソースをインストールします。
Breezeを使用する場合、ReactまたはVueを利用することもできますが、参考サイトと同様に、デフォルトのbladeを利用する方法で記載します。
1 |
php artisan breeze:install |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
l Which Breeze stack would you like to install? qqqqqqqqqqqqqqqk x Blade with Alpine x mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj l Would you like dark mode support? qqqqqqqqqqqqqqqqqqqqqqqqqqqk x No x mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj l Which testing framework do you prefer? qqqqqqqqqqqqqqqqqqqqqqk x PHPUnit x mqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqqj INFO Installing and building Node dependencies. npm WARN EBADENGINE Unsupported engine { npm WARN EBADENGINE package: 'laravel-vite-plugin@1.0.1', npm WARN EBADENGINE required: { node: '^18.0.0 || >=20.0.0' }, npm WARN EBADENGINE current: { node: 'v16.13.2', npm: '8.19.1' } npm WARN EBADENGINE } npm WARN EBADENGINE Unsupported engine { npm WARN EBADENGINE package: 'vite@5.0.12', npm WARN EBADENGINE required: { node: '^18.0.0 || >=20.0.0' }, npm WARN EBADENGINE current: { node: 'v16.13.2', npm: '8.19.1' } npm WARN EBADENGINE } npm WARN EBADENGINE Unsupported engine { npm WARN EBADENGINE package: 'lru-cache@10.2.0', npm WARN EBADENGINE required: { node: '14 || >=16.14' }, npm WARN EBADENGINE current: { node: 'v16.13.2', npm: '8.19.1' } npm WARN EBADENGINE } npm WARN EBADENGINE Unsupported engine { npm WARN EBADENGINE package: 'rollup@4.9.6', npm WARN EBADENGINE required: { node: '>=18.0.0', npm: '>=8.0.0' }, npm WARN EBADENGINE current: { node: 'v16.13.2', npm: '8.19.1' } npm WARN EBADENGINE } added 144 packages, and audited 145 packages in 18s 34 packages are looking for funding run `npm fund` for details found 0 vulnerabilities npm notice npm notice New major version of npm available! 8.19.1 -> 10.4.0 npm notice Changelog: https://github.com/npm/cli/releases/tag/v10.4.0 npm notice Run npm install -g npm@10.4.0 to update! npm notice > build > vite build vite v5.0.12 building for production... ✓ 48 modules transformed. public/build/manifest.json 0.26 kB x gzip: 0.13 kB public/build/assets/app-03ONKLKm.css 31.81 kB x gzip: 6.08 kB public/build/assets/app-JzZ5dANH.js 73.42 kB x gzip: 27.22 kB ✓ built in 2.27s INFO Breeze scaffolding installed successfully. |
日本語化
app.phpの変更
1 2 3 4 5 6 7 8 9 |
'timezone' => 'UTC', 'locale' => 'en', 'fallback_locale' => 'en', ↓ 'timezone' => 'Asia/Tokyo', 'locale' => 'ja', 'fallback_locale' => 'ja_JP', |
日本語ファイルの追加
Laravelは多言語化に対応しています。
「lang」ディレクトリに日本語用のファイルを追加します。
1 |
composer require --dev laravel-lang/lang laravel-lang/publisher |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
./composer.json has been updated Running composer update laravel-lang/lang laravel-lang/publisher Loading composer repositories with package information Updating dependencies Lock file operations: 13 installs, 0 updates, 0 removals - Locking archtechx/enums (v1.0.1) - Locking composer/semver (3.4.0) - Locking dragon-code/contracts (2.22.0) - Locking dragon-code/pretty-array (v4.1.0) - Locking dragon-code/support (6.12.0) - Locking laravel-lang/lang (14.2.9) - Locking laravel-lang/locale-list (1.3.0) - Locking laravel-lang/locales (2.5.0) - Locking laravel-lang/native-country-names (1.3.0) - Locking laravel-lang/native-currency-names (1.3.0) - Locking laravel-lang/native-locale-names (2.2.0) - Locking laravel-lang/publisher (16.2.0) - Locking symfony/polyfill-php81 (v1.29.0) Writing lock file Installing dependencies from lock file (including require-dev) Package operations: 13 installs, 0 updates, 0 removals - Downloading dragon-code/contracts (2.22.0) - Downloading symfony/polyfill-php81 (v1.29.0) - Downloading dragon-code/support (6.12.0) - Downloading laravel-lang/native-locale-names (2.2.0) - Downloading laravel-lang/native-currency-names (1.3.0) - Downloading laravel-lang/native-country-names (1.3.0) - Downloading archtechx/enums (v1.0.1) - Downloading laravel-lang/locale-list (1.3.0) - Downloading laravel-lang/locales (2.5.0) - Downloading dragon-code/pretty-array (v4.1.0) - Downloading composer/semver (3.4.0) - Downloading laravel-lang/publisher (16.2.0) - Downloading laravel-lang/lang (14.2.9) - Installing dragon-code/contracts (2.22.0): Extracting archive - Installing symfony/polyfill-php81 (v1.29.0): Extracting archive - Installing dragon-code/support (6.12.0): Extracting archive - Installing laravel-lang/native-locale-names (2.2.0): Extracting archive - Installing laravel-lang/native-currency-names (1.3.0): Extracting archive - Installing laravel-lang/native-country-names (1.3.0): Extracting archive - Installing archtechx/enums (v1.0.1): Extracting archive - Installing laravel-lang/locale-list (1.3.0): Extracting archive - Installing laravel-lang/locales (2.5.0): Extracting archive - Installing dragon-code/pretty-array (v4.1.0): Extracting archive - Installing composer/semver (3.4.0): Extracting archive - Installing laravel-lang/publisher (16.2.0): Extracting archive - Installing laravel-lang/lang (14.2.9): Extracting archive 3 package suggestions were added by new dependencies, use `composer suggest` to see details. Generating optimized autoload files > Illuminate\Foundation\ComposerScripts::postAutoloadDump > @php artisan package:discover --ansi INFO Discovering packages. laravel-lang/lang ........................................................................................ DONE laravel-lang/locales ..................................................................................... DONE laravel-lang/publisher ................................................................................... DONE laravel/breeze ........................................................................................... DONE laravel/sail ............................................................................................. DONE laravel/sanctum .......................................................................................... DONE laravel/tinker ........................................................................................... DONE nesbot/carbon ............................................................................................ DONE nunomaduro/collision ..................................................................................... DONE nunomaduro/termwind ...................................................................................... DONE spatie/laravel-ignition .................................................................................. DONE 88 packages you are using are looking for funding. Use the `composer fund` command to find out more! > @php artisan vendor:publish --tag=laravel-assets --ansi --force INFO No publishable resources for tag [laravel-assets]. No security vulnerability advisories found Using version ^14.2 for laravel-lang/lang Using version ^16.2 for laravel-lang/publisher |
1 |
php artisan lang:add ja |
1 2 3 4 5 6 7 8 9 10 11 12 |
INFO LaravelLang\Lang\Plugin. Collect source ....................................................................................... 2ms DONE Collecting ja ........................................................................................ 1ms DONE INFO Storing changes... ja.json .............................................................................................. 2ms DONE ja/auth.php .......................................................................................... 1ms DONE ja/pagination.php .................................................................................... 0ms DONE ja/passwords.php ..................................................................................... 0ms DONE ja/validation.php .................................................................................... 3ms DONE |
lang/ja.json を以下の内容に書き換えます。
https://github.com/Laravel-Lang/lang/blob/main/locales/ja/json.json
参考サイトの説明通りに、日本語用のファイルを追加後は、ライブラリ不要なのでアンインストールします。
1 |
composer remove --dev laravel-lang/lang laravel-lang/publisher |
validation.phpには、attributesが定義されていないので、カスタマイズします。
1 2 3 4 5 6 7 8 9 10 |
return [ … (省略) … 'attributes' => [ 'name' => 'ユーザー名', 'email' => 'メールアドレス', 'password' => 'パスワード', ], ]; |
メール認証を有効化する
ユーザー登録時のメール認証がデフォルトでは無効になっているため、有効化します。
Userモデル(app/Models/User.php)を修正します。
use文がコメントアウトを外します。
1 |
use Illuminate\Contracts\Auth\MustVerifyEmail; |
MustVerifyEmailをインプリメントします。
ユーザー登録後に表示するダッシュボードは、メール認証が完了していないと表示できないように制限を掛けます。
「routes/web.php」を変更します。
middlewareに「verified」を追加します。
1 2 3 |
Route::get('/dashboard', function () { return view('dashboard'); })->middleware(['auth', 'verified'])->name('dashboard'); |
動作確認
以上で実装は完了となります。
動作確認をして、問題なければ、マルチログインの実装に進みます。
マルチログインの実装
モデルの作成
デフォルトの認証では、usersテーブルを利用しますが、本記事では、それに加えてadminsテーブルを作成して、認証情報を管理するようにします。
管理者サイトの認証では、adminsテーブルを参照するようになります。
以下のようにモデルファイルとマイグレーションファイルを作成します。
1 |
php artisan make:model Admin -m |
モデルの内容は、デフォルト(User.php)と同じにしておきます。
マイグレーションファイルもデフォルト(usersテーブル)と同じにしておきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
<?php use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { /** * Run the migrations. * * @return void */ public function up() { Schema::create('admins', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); } /** * Reverse the migrations. * * @return void */ public function down() { Schema::dropIfExists('admins'); } }; |
マイグレーションを行います。
1 |
php artisan migrate |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
INFO Preparing database. Creating migration table ............................................................................. 9ms DONE INFO Running migrations. 2014_10_12_000000_create_users_table ................................................................ 17ms DONE 2014_10_12_100000_create_password_reset_tokens_table ................................................. 5ms DONE 2019_08_19_000000_create_failed_jobs_table .......................................................... 14ms DONE 2019_12_14_000001_create_personal_access_tokens_table ............................................... 23ms DONE 2024_02_06_061505_create_admins_table ............................................................... 11ms DONE [hogehoge@demo laravel]$ /usr/bin/php8.1 artisan make:controller Admin\Auth\LoginController INFO Controller [app/Http/Controllers/AdminAuthLoginController.php] created successfully. |
ガードの設定
デフォルトのガードに加え、admin用のガードを追加します。
/config/auth.php を修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
<?php return [ ︙ (中略) ︙ 'guards' => [ 'web' => [ 'driver' => 'session', 'provider' => 'users', ], 'admin' => [ // 追加 'driver' => 'session', // 追加 'provider' => 'admins', // 追加 ], // 追加 ], ︙ (中略) ︙ 'providers' => [ 'users' => [ 'driver' => 'eloquent', 'model' => App\Models\User::class, ], 'admins' => [ // 追加 'driver' => 'eloquent', // 追加 'model' => App\Models\Admin::class, // 追加 ], // 追加 ], ︙ (中略) ︙ 'passwords' => [ 'users' => [ 'provider' => 'users', 'table' => 'password_resets', 'expire' => 60, 'throttle' => 60, ], 'admins' => [ // 追加 'provider' => 'admins', // 追加 'table' => 'password_resets', // 追加 'expire' => 60, // 追加 'throttle' => 60, // 追加 ], // 追加 ], ︙ (中略) ︙ ]; |
ルーティングの設定
ルーティングを追加します。
デフォルトではroutes/auth.php に記載されているので、/routes/admin.php を作成して、同様に設定します。
各コントローラーのパスが変わるのと、指定するmiddlewareを「admin」にしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
<?php use App\Http\Controllers\Admin\Auth\AuthenticatedSessionController; use App\Http\Controllers\Admin\Auth\ConfirmablePasswordController; use App\Http\Controllers\Admin\Auth\EmailVerificationNotificationController; use App\Http\Controllers\Admin\Auth\EmailVerificationPromptController; use App\Http\Controllers\Admin\Auth\NewPasswordController; use App\Http\Controllers\Admin\Auth\PasswordController; use App\Http\Controllers\Admin\Auth\PasswordResetLinkController; use App\Http\Controllers\Admin\Auth\RegisteredUserController; use App\Http\Controllers\Admin\Auth\VerifyEmailController; use Illuminate\Support\Facades\Route; Route::middleware('guest:admin')->group(function () { Route::get('register', [RegisteredUserController::class, 'create']) ->name('register'); Route::post('register', [RegisteredUserController::class, 'store']); Route::get('login', [AuthenticatedSessionController::class, 'create']) ->name('login'); Route::post('login', [AuthenticatedSessionController::class, 'store']); Route::get('forgot-password', [PasswordResetLinkController::class, 'create']) ->name('password.request'); Route::post('forgot-password', [PasswordResetLinkController::class, 'store']) ->name('password.email'); Route::get('reset-password/{token}', [NewPasswordController::class, 'create']) ->name('password.reset'); Route::post('reset-password', [NewPasswordController::class, 'store']) ->name('password.store'); }); Route::middleware('auth:admin')->group(function () { Route::get('verify-email', [EmailVerificationPromptController::class, '__invoke']) ->name('verification.notice'); Route::get('verify-email/{id}/{hash}', [VerifyEmailController::class, '__invoke']) ->middleware(['signed', 'throttle:6,1']) ->name('verification.verify'); Route::post('email/verification-notification', [EmailVerificationNotificationController::class, 'store']) ->middleware('throttle:6,1') ->name('verification.send'); Route::get('confirm-password', [ConfirmablePasswordController::class, 'show']) ->name('password.confirm'); Route::post('confirm-password', [ConfirmablePasswordController::class, 'store']); Route::put('password', [PasswordController::class, 'update'])->name('password.update'); Route::post('logout', [AuthenticatedSessionController::class, 'destroy']) ->name('logout'); }); |
作成したadmin.phpをweb.phpから読み込むために、以下を追加します。
プレフィックスに「admin」を付けて、ルーティングするようにしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
use App\Http\Controllers\ProfileController as ProfileOfAdminController; ︙ (中略) ︙ Route::prefix('admin')->name('admin.')->group(function(){ Route::get('/dashboard', function () { return view('admin.dashboard'); })->middleware(['auth:admin', 'verified'])->name('dashboard'); Route::middleware('auth:admin')->group(function () { Route::get('/profile', [ProfileOfAdminController::class, 'edit'])->name('profile.edit'); Route::patch('/profile', [ProfileOfAdminController::class, 'update'])->name('profile.update'); Route::delete('/profile', [ProfileOfAdminController::class, 'destroy'])->name('profile.destroy'); }); require __DIR__.'/admin.php'; }); |
クッキーの設定
クッキーに関しても、admin用を追加します。
config/session.php を修正します。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
<?php use Illuminate\Support\Str; return [ ︙ (中略) ︙ 'cookie' => env( 'SESSION_COOKIE', Str::slug(env('APP_NAME', 'laravel'), '_').'_session' ), 'cookie_admin' => Str::slug(env('APP_NAME', 'laravel'), '_').'_session_admin', // 追加 |
adminの場合は、上記で追加した設定を使用するようにします。
app/Providers/AppServiceProvider.php を修正します。
1 2 3 4 5 6 |
public function boot() { if (request()->is('admin/*')) { config(['session.cookie' => config('session.cookie_admin')]); } } |
コントローラーの作成
コントローラーを作成します。
デフォルトの認証機能をコピーして、admin用を作成します。
パスを /app/Http/Controllers/Admin としています。
デフォルトの認証機能である /app/Http/Controllers/Auth をコピーして、/app/Http/Controllers/Admin/Auth とします。
また、ProfileControllerなど、auth配下以外のファイルも同様にコピーして作成します。
ユーザー登録
/admin/register へのアクセスで、RegisteredUserController.phpのcreateメソッドが実行されるので、ビューの指定をadmin用に変更します。
1 2 3 4 |
public function create(): View { return view('admin.auth.register'); } |
また、ログインページへのリンクがあるので、リンク先を変更します。
1 |
<a (中略) href="{{ route('admin.login') }}"> |
続いて、送信時にユーザーの登録を行うRegisteredUserController.phpのstoreメソッドを変更します。
以下の内容をadmin用に変更します。
メールアドレスのバリデーションで、ユニークチェックはadminsテーブルに対して行う
対象モデルをAdminに変更
登録後に自動でログインを行う際のガードをadmin用に変更
処理完了後のリダイレクト先をadmin用のダッシュボードに変更
ビューは、送信先をadmin用に変更します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
<form method="POST" action="{{ route('admin.register') }}"> public function store(Request $request): RedirectResponse { $request->validate([ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:'.Admin::class], 'password' => ['required', 'confirmed', Rules\Password::defaults()], ]); $user = Admin::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); event(new Registered($user)); Auth::guard('admin')->login($user); return redirect(RouteServiceProvider::ADMIN_HOME); } |
リダイレクト先はapp/Providers/RouteServiceProvider.phpに定義されているので、admin用を追加します。
1 |
public const ADMIN_HOME = '/admin/dashboard'; |
ダッシュボード
ユーザー登録が完了すると、ダッシュボードが表示されます。
まず、レイアウトファイルを変更します。
resources/views/layouts/app.blade.php をコピーして、resources/views/layouts/admin.blade.php を作成します。
ナビゲーションメニューがインクルードされているので、admin用に変更します。
1 |
@include('layouts.admin_navigation') |
ナビゲーションメニューも同様に、resources/views/layouts/navigation.blade.php をコピーして、resources/views/layouts/admin_navigation.blade.php を作成します。
admin用に以下を変更します。(レスポンシブ用も同様に変更)
ダッシュボードのリンク先(2箇所、内1つはrouteIsの判定も変更)
プロフィールのリンク先
ログアウトの送信先とリンク先
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
︙ (中略) ︙ <div class="shrink-0 flex items-center"> <a href="{{ route('admin.dashboard') }}"> <x-application-logo class="block h-9 w-auto fill-current text-gray-800" /> </a> </div> <!-- Navigation Links --> <div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex"> <x-nav-link :href="route('admin.dashboard')" :active="request()->routeIs('admin.dashboard')"> {{ __('Dashboard') }} </x-nav-link> </div> ︙ (中略) ︙ <x-dropdown-link :href="route('admin.profile.edit')"> {{ __('Profile') }} </x-dropdown-link> <!-- Authentication --> <form method="POST" action="{{ route('admin.logout') }}"> @csrf <x-dropdown-link :href="route('admin.logout')" onclick="event.preventDefault(); this.closest('form').submit();"> {{ __('Log Out') }} </x-dropdown-link> </form> |
dashboard.blade.phpで使用するレイアウトを変更します。
1 2 |
<x-admin-layout> </x-admin-layout> |
また、app/View/Components/AppLayout.php をコピーして、app/View/Components/AdminLayout.php を作成します。
1 2 3 4 5 6 7 8 9 10 |
︙ (中略) ︙ class AdminLayout extends Component { public function render(): View { return view('layouts.admin'); } } |
また、未ログインでダッシュボードにアクセスした場合は、ログインにリダイレクトするようにします。
app/Http/Middleware/Authenticate.php を変更します。
admin用のリクエスト判定を追加し、adminの場合は、admin用のログインのルーティングを返します。
1 2 3 4 |
if (! $request->expectsJson()) { if($request->is('admin/*')) return route('admin.login'); return route('login'); } |
ログイン
/admin/login へのアクセスで、AuthenticatedSessionController.phpのcreateメソッドが実行されるので、ビューの指定をadmin用に変更します。
1 2 3 4 |
public function create(): View { return view('admin.auth.login'); } |
ビューは、送信先をadmin用に変更します。
1 |
<form method="POST" action="{{ route('admin.login') }}"> |
また、パスワードを忘れた場合のリンクがあるので、リンク先を変更します。
1 2 3 4 5 |
@if (Route::has('admin.password.request')) <a (中略) href="{{ route('admin.password.request') }}"> {{ __('Forgot your password?') }} </a> @endif |
ログイン時の認証チェックがapp/Http/Requests/Auth/LoginRequest.php で行われます。
admin用のガードを利用してチェックを行うようにします。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
public function authenticate(): void { $this->ensureIsNotRateLimited(); $this->is('admin/*') ? $guard = 'admin' : $guard = 'web'; if (! Auth::guard($guard)->attempt($this->only('email', 'password'), $this->boolean('remember'))) { RateLimiter::hit($this->throttleKey()); throw ValidationException::withMessages([ 'email' => trans('auth.failed'), ]); } RateLimiter::clear($this->throttleKey()); } |
ログイン後はダッシュボードにリダイレクトするようにします。
1 2 3 4 5 6 7 8 |
public function store(LoginRequest $request): RedirectResponse { $request->authenticate(); $request->session()->regenerate(); return redirect()->intended(RouteServiceProvider::ADMIN_HOME); } |
また、ログイン済みでログインにアクセスした場合は、ダッシュボードにリダイレクトするようにします。
app/Http/Middleware/RedirectIfAuthenticated.php を変更します。
ログインチェックをしているところで、admin用のガード判定を追加し、adminの場合は、admin用のダッシュボードにリダイレクトするようにします。
1 2 3 4 |
if (Auth::guard($guard)->check()) { if($guard == 'admin') return redirect(RouteServiceProvider::ADMIN_HOME); // 追加 return redirect(RouteServiceProvider::HOME); } |
ログアウト
ログアウト時は、AuthenticatedSessionController.phpのdestoryメソッドが実行されます。
以下をadmin用に変更します。
ログアウト時に利用するガードを変更する
ログアウト後のリダイレクト先を変更する
1 2 3 4 5 6 7 8 9 10 |
public function destroy(Request $request): RedirectResponse { Auth::guard('admin')->logout(); $request->session()->invalidate(); $request->session()->regenerateToken(); return redirect('/admin/login'); } |
管理サイトの動作確認
管理サイトのlogin にて、ログイン完了後に管理者用のダッシュボードが表示されていれば正常に動作しています。
参考サイト
Laravel9のBreezeで、ユーザー登録・ログインを実装する
https://specially198.com/implement-user-registration-and-login-with-breeze-of-laravel9/
Laravel9のBreezeで、マルチログインを実装する
https://specially198.com/implement-multi-login-with-laravel9-breeze/