Categories: PHP

Laravel 6 以使用者帳號名稱或 Email 信箱登入教學

介紹如何修改 Laravel 網頁專案,將預設的 Email 登入方式改為使用者帳號登入。

建立基本 Laravel 專案

首先參考 Laravel 6 建立含有使用者註冊、登入認證功能的網頁專案教學,建立好基本的 Laravel 專案,然後在執行 migrate 之前,編輯 database/migrations/2014_10_12_000000_create_users_table.php 這一個建立使用者資料表的 migration 設定檔,在其中加入一欄用於儲存使用者名稱的 username 欄位:

public function up()
{
    Schema::create('users', function (Blueprint $table) {
        $table->bigIncrements('id');
        $table->string('name');
        $table->string('username');  // 加入使用者名稱欄位
        $table->string('email')->unique();
        $table->timestamp('email_verified_at')->nullable();
        $table->string('password');
        $table->rememberToken();
        $table->timestamps();
    });
}

修改好之後,回到 Laravel 專案目錄,執行 migrate

# 建立資料庫結構
php artisan migrate

這樣在使用者資訊的資料表中,就會有一個可以儲存帳號名稱的 username 欄位了,如果還需要除存使用者的其他資訊(例如電話、地址等),也可以依照這種方式在上面這個 migration 設定檔中加入所需的欄位,而可用的欄位資料型別可以直接參考 Laravel 的 migrations 說明文件

使用者註冊 View

修改使用者註冊表單的 View,編輯 resources/views/auth/register.blade.php 這一個 blade 檔案,在其中加入使用者帳號名稱(username)的欄位:

<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>

使用者註冊 Controller

接著修改使用者註冊表單的 Controller,編輯 app/Http/Controllers/Auth/RegisterController.php,修改 validator 這個驗證者資料的函數,加入驗證使用者名稱的條件:

protected function validator(array $data)
{
    return Validator::make($data, [
        'name' => ['required', 'string', 'max:255'],
        'username' => ['required', 'string', 'max:255', 'unique:users'],  // 驗證使用者帳號名稱
        'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
        'password' => ['required', 'string', 'min:8', 'confirmed'],
    ]);
}

接著在下方建立使用者的地方,也要加入使用者帳號名稱欄位:

protected function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'username' => $data['username'],  // 使用者帳號名稱
        'email' => $data['email'],
        'password' => Hash::make($data['password']),
    ]);
}

使用者登入 View

修改使用者登入網頁的 View,編輯 resources/views/auth/login.blade.php 這一個 blade 檔案,將其中的 Email 欄位改為使用者帳號名稱(username):

<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>

使用者登入 Controller

接著修改使用者登入的 Controller,編輯 app/Http/Controllers/Auth/LoginController.php,將 AuthenticatesUsersusername() 函數覆寫掉:

class LoginController extends Controller
{
    // ...

    /**
     * Get the login username to be used by the controller.
     *
     * @return string
     */
    public function username()
    {
        return 'username';
    }
}

AuthenticatesUsers 的原始碼位於 vendor/laravel/framework/src/Illuminate/Foundation/Auth 目錄之下,其原本的 username() 函數是傳回 email,這裡我們將其改為 username,這樣就可以改用使用者的帳號名稱來登入。

User 類別

修改 app/User.php,在 $fillable 中加入 username 欄位:

// 加入 username
protected $fillable = [
    'name', 'email', 'password', 'username',
];

啟動網頁伺服器

以上的各部份都修改完成後,即可啟動 Laravel 的開發用網頁伺服器,測試結果了。

# 執行網頁伺服器
php artisan serve --port=18000
使用者註冊網頁
使用者登入網頁

使用者帳號名稱或 Email 信箱登入

如果想要讓使用者在登入時,可以自由輸入帳號名稱或 Email 信箱來登入,可以修改使用者登入 Controller(app/Http/Controllers/Auth/LoginController.php),將 AuthenticatesUsersusername() 函數覆寫成這樣:

public function username()
{
    // 取得 username 欄位
    $value = request()->input('username');

    // 根據輸入的資料判斷欄位
    $fieldType = filter_var($value, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';

    // 將轉換後的欄位放回 request 中
    request()->merge([$fieldType => $value]);

    // 傳回欄位名稱
    return $fieldType;
}

這裡我們使用 filter_var 來判斷使用者輸入的資料是否為 Email,若為 Email 則使用 Email 加上密碼認證,若不是 Email 則使用帳號名稱加上密碼來認證。

參考資料:tutsforweb

Share
Published by
Office Guide
Tags: Laravel

Recent Posts

Python 使用 PyAutoGUI 自動操作滑鼠與鍵盤

本篇介紹如何在 Python ...

9 個月 ago

Ubuntu Linux 以 WireGuard 架設 VPN 伺服器教學與範例

本篇介紹如何在 Ubuntu ...

9 個月 ago

Linux 網路設定 ip 指令用法教學與範例

本篇介紹如何在 Linux 系...

9 個月 ago

Windows 使用 TPM 虛擬智慧卡保護 SSH 金鑰教學與範例

本篇介紹如何在 Windows...

11 個月 ago

Linux 以 Shamir’s Secret Sharing 分割保存金鑰教學與範例

介紹如何在 Linux 中使用...

11 個月 ago

Linux 以 Cryptsetup、LUKS 加密 USB 隨身碟教學與範例

介紹如何在 Linux 系統中...

11 個月 ago