介紹如何修改 Laravel 網頁專案,將預設的 Email 登入方式改為使用者帳號登入。
建立基本 Laravel 專案
首先參考 Laravel 6 建立含有使用者註冊、登入認證功能的網頁專案教學,建立好基本的 Laravel 專案,然後在執行 migrate 之前,編輯 database/migrations/2014_10_12_000000_create_users_table.php 這一個建立使用者資料表的 migration 設定檔,在其中加入一欄用於儲存使用者名稱的 username 欄位:
<?php
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 這個驗證者資料的函數,加入驗證使用者名稱的條件:
<?php
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'],
]);
}
?>
接著在下方建立使用者的地方,也要加入使用者帳號名稱欄位:
<?php
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,將 AuthenticatesUsers 的 username() 函數覆寫掉:
<?php
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 欄位:
<?php
// 加入 username
protected $fillable = [
'name', 'email', 'password', 'username',
];
?>
啟動網頁伺服器
以上的各部份都修改完成後,即可啟動 Laravel 的開發用網頁伺服器,測試結果了。
# 執行網頁伺服器
php artisan serve --port=18000


使用者帳號名稱或 Email 信箱登入
如果想要讓使用者在登入時,可以自由輸入帳號名稱或 Email 信箱來登入,可以修改使用者登入 Controller(app/Http/Controllers/Auth/LoginController.php),將 AuthenticatesUsers 的 username() 函數覆寫成這樣:
<?php
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 則使用帳號名稱加上密碼來認證。
