Laravel 客製密碼欄位驗證

一般情況下

驗證的方法

  • Controller
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    $validation = $request->validated();

    $credentials = [
    'email' => $validation['phone'],
    'password' => $validation['password'],
    ];

    if (!Auth::guard('member')->attempt($credentials)) {
    throw AuthorizeException::loginFail();
    }

如果密碼欄位包含 password 關鍵字處理方法

  • Model\Member.php
    1
    2
    3
    4
    public function getAuthPassword()
    {
    return $this->member_password;
    }

特殊情況

但當遇到密碼欄位沒有 password 關鍵字的時候都會驗證失敗

解決辦法

由於既有的取得User Model 的 function 會將 $credentials array 中的 password 過濾掉,不會加進條件中

由客製化的驗證密碼如果非 password 字串,會導致無法取得 User Model,
所以我們需要自己實作一個 UserProvider 來取代原本的 EloquentUserProvider

  • 原生的 function
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    public function retrieveByCredentials(#[\SensitiveParameter] array $credentials)
    {
    $credentials = array_filter(
    $credentials,
    fn ($key) => ! str_contains($key, 'password'),
    ARRAY_FILTER_USE_KEY
    );

    if (empty($credentials)) {
    return;
    }
    ...
    }

複寫 retrieveByCredentials method

MemberUserProvider.php

直接指定 credentials 的 key 為 phone

1
2
3
4
5
6
public function retrieveByCredentials(array $credentials)
{
$query = $this->createModel()->newQuery();

return $query->where('phone', $credentials['phone'])->first();
}

參考資料:
https://github.com/tymondesigns/jwt-auth/issues/1551