プロミツの技術メモ

お仕事や個人開発で得た技術周りの知見、考えたことなどを記録していくブログ

Laravelでemail/ユーザー登録無しの認証機構を作る

ども、プロミツです。

Laravelはrailsとかとは違って、標準で認証機構をもっているので、

$ php artisan make:auth

とか、Laravel6.xなら

$ composer require laravel/ui --dev

とかすると、email/passwordによるユーザー登録/ログイン・ログアウト/パスワードリセットなどの機能(ビューとルーティング定義)を生成することができます。 これは一般的な認証付きウェブアプリを作成する場合には大変便利なのですが、たまに「emailを使わずに、ユーザー登録もさせないで管理者がアカウントを作る」というような仕様のシステムを作る場合があります(簡易な社内システムとか) この場合、Laravel標準の認証機構ではtoo muchなので、不要な機能を極力無効化してみようと思います。

環境

Laravel ver6.xを想定します。

手順

まず、普通にLaravelのプロジェクトを生成し、プロジェクトディレクトリに移動します。

$ laravel new test_auth
$ cd test_auth

次に、Laravelの認証機構のビューとルーティング定義を生成します。

$ composer require laravel/ui --dev
$ php artisan ui vue --auth

※ 今回はフロントのフレームワークをvue.jsにしましたが、他に標準でreact、bootstrapが利用でき、サードパーティーのフロントエンドプリセットを使うと、他のCSSフレームワークなども利用することができます。

ex) bulma

$ composer require laravel-frontend-presets/bulma
$ php artisan preset bulma-auth 

github.com

これで、指定したフロントエンドフレームワークのモジュールが利用可能になり、さらに認証関連のビューリソースが生成されます。 ついでに、必要なフロントエンド用のモジュールもプロジェクトに追加しておきます。

$ npm install

次に、マイグレーションファイルのusersテーブル生成コードを修正します。

database/migrations/2014_10_12_000000_create_users_table.php

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->bigIncrements('id');
            $table->string('name');
            $table->string('username')->unique();
            // $table->string('email')->unique();
            // $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

  ...
}

ログインID用にusername カラムを追加し、email/ email_verified_at カラムをコメントアウト(後で必要になった場合、追加のマイグレーションファイル作成時にカラム名を参照するため)します。 (remembetToken()も必要ない気がしたけど、怒られたのでコメントアウトしない←あとで調べる)

ユーザーIDをemailからusernameに変更する

app/Http/Controllers/Auth/LoginController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class LoginController extends Controller
{

...

    public function username()
    {
        return 'username';
    }
}

合わせて、ログイン画面のviewも直しておきます。

 ...
                   <form method="POST" action="{{ route('login') }}">
                        @csrf

                        <div class="form-group row">
                            <label for="username" class="col-md-4 col-form-label text-md-right">{{ __('Username') }}</label>

                            <div class="col-md-6">
                                <input id="username" type="text" class="form-control @error('username') is-invalid @enderror" name="username" value="{{ old('username') }}" required autocomplete="username" autofocus>

                                @error('username')
                                    <span class="invalid-feedback" role="alert">
                                        <strong>{{ $message }}</strong>
                                    </span>
                                @enderror
                            </div>
                        </div>
 ...

↑ emailの部分をusernameに変更

さらに、ルーティングの定義を修正して、不要なルートを無効化しておきます。

routes/web.php

<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function () {
    return view('welcome');
});

Auth::routes(array('register' => false, 'reset' => false, 'confirm' => false, 'verify' => false));

Route::get('/home', 'HomeController@index')->name('home');

このように修正することで、ログイン/ログアウト以外のルーティングを無効化できます。

次に、データベース設定を自分の環境に合わせて修正します。

...
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=your_database_name
DB_USERNAME=yourname
DB_PASSWORD=yourpassword
...

これでセットアップは終わったので、後はいつものようにマイグレーションを実行し

$ php artisan migrate

フロントエンドのリソースをビルドして、

$ npm run dev

サーバを立ち上げて、http://127.0.0.1:8000にアクセスすると、

f:id:promitsu:20191202215756p:plain

Loginボタンをクリックすると、

f:id:promitsu:20191202215822p:plain

ですが、このままではユーザーデータが存在せず、ログインできないので、Tinkerを使ってユーザーを追加します。

$ php artisan tinker
Psy Shell v0.9.11 (PHP 7.3.11-1+ubuntu18.04.1+deb.sury.org+1 — cli) by Justin Hileman
>> $user = new App\User();
=> App\User {#3016}
>>> $user->password = Hash:make('yourpassword');
PHP Parse error: Syntax error, unexpected ':' on line 1
>>> $user->password = Hash::make('yourpassword');
=> "$2y$10$ocVcKNTP.wFX8L48YlwZce5VeZ9ZEbCZY/StlbXehjqqZc.2m4wKK"
>>> $user->username = 'test';
=> "test"
>>> $user->name = 'Test';
=> "Test"
>>> $user->save();
=> true

こんな感じでユーザーを作成して、ログインしてみると

f:id:promitsu:20191202220650p:plain

無事成功して、ダッシュボード画面が表示されました。

あとは、さっきのTinkerでやったユーザー作成を管理画面とかのユーザー登録機能の実装に書けば良い感じですかね。 今回無効化した機能のControllerやViewはあえて削除せずに残してますが、本当に不要なら削除したほうが要らぬ混乱を招かなくて良いかもですね。

それでは~。