# Laravel 密碼檢查通用Rule ###### tags: `PHP` `Laravel 5.8` --- * **目的** 因應各種不同專案時,每個客戶往往對於密碼設置有不同的要求,但是實際分析,密碼規則也往往通常是那幾種條件,故有調整成可設定性的方向開發,希望以後有遇到時,能直接重複使用XD。(當然,依照需求的不同,可以視情況新增修改規則) * **程式碼** 以下就先廢話不多說,直接上CODE(使用Laravel Validation Rule的方式) ```php <?php namespace App\Rules; use Illuminate\Contracts\Validation\Rule; /** * 密碼檢查使用 * (schema 可視情況調整) * * Class PasswordValidation * @package App\Rules */ class PasswordValidation implements Rule { /** * @var int 最少的密碼長度 */ protected $lengthLimit = 8; /** * @var bool 是否檢查與帳號不能相同 */ protected $checkNotSameAsAccount = true; /** * @var string 如果 $checkNotSameAsAccount = true 時 為必填 */ protected $accountValue = ''; /** * @var bool 是否檢查至少要一個 大寫英文 */ protected $checkRequiredUppercase = true; /** * @var bool 是否檢查至少要一個 小寫英文 */ protected $checkRequiredLowercase = true; /** * @var bool 是否檢查至少要一個 數字 */ protected $checkRequiredNumber = true; /** * @var bool 是否檢查至少要一個 特殊符號 */ protected $checkRequiredSpecialSymbol = true; protected $errorMsg = ''; public function __construct(array $setting = []) { // 可以客製化調整 if ($setting) { foreach ($setting as $key => $value) { if (property_exists(self::class, $key)) { $this->$key = $value; } } } } public function passes($attribute, $value) { if (is_integer($this->lengthLimit) && $this->lengthLimit > 0) { if (!preg_match('/^.{' . $this->lengthLimit . ',}$/', $value)) { $this->errorMsg = '密碼需要至少' . $this->lengthLimit . '個字元'; return false; } } if ($this->checkNotSameAsAccount === true) { if (!$this->accountValue || !is_string($this->accountValue)) { throw new \Exception('檢查帳號與密碼不能相同時,需要帳號資訊'); } if ($this->accountValue === $value) { $this->errorMsg = '密碼不能與帳號相同'; return false; } } if ($this->checkRequiredUppercase === true) { if (!preg_match('/[A-Z]{1}/', $value)) { $this->errorMsg = '密碼需要至少1個大寫英文字母'; return false; } } if ($this->checkRequiredLowercase === true) { if (!preg_match('/[a-z]{1}/', $value)) { $this->errorMsg = '密碼需要至少1個小寫英文字母'; return false; } } if ($this->checkRequiredNumber === true) { if (!preg_match('/[0-9]{1}/', $value)) { $this->errorMsg = '密碼需要至少1個數字'; return false; } } if ($this->checkRequiredSpecialSymbol === true) { if (!preg_match('/[@$!%*?&]{1}/', $value)) { $this->errorMsg = '密碼需要至少1個特殊字元'; return false; } } return true; } public function message() { $msg = '密碼格式不正確' . ($this->errorMsg ? ':' . $this->errorMsg : ''); return $msg; } } ``` * **目前檢查規則** 1. 密碼長度 2. 密碼設定可否與帳號相同 3. 密碼是否需要至少一個「大寫英文」 4. 密碼是否需要至少一個「小寫英文」 5. 密碼是否需要至少一個「數字」 6. 密碼是否需要至少一個「特殊符號」(目前允許特殊符號:@$!%*?&) * **使用方式** 1. Validation,寫在Request時 ![](https://i.imgur.com/bWLUzPx.png) 2. 直接用Validation檢查(e.g. 可以使用在Observer,Model saving的event中) ![](https://i.imgur.com/Ha1TMGK.png) 3. 客製化調整,可於創建式時,設置檢查開關(預設值為全部都開啟)(e.g. 不檢查第二點帳號和第五點數字,如下圖) ![](https://i.imgur.com/FAsDU1K.png) * **注意事項** 1. 「密碼設定可否與帳號相同」需要帶入帳號(accountValue)的參數,可於創建式時帶入 2. 「密碼長度」,目前只有最小字元數(最大字元數需視TABLE SCHEMA調整) 3. 預設值檢查為全部都開啟 --- * **小結** 希望能夠看是否能幫助到人XD,以及自己未來能夠使用,也希望如果有什麼想法能夠也回饋給筆者,像是有什麼更良好的架構使用方式...等,或者是調整方向(包裝成package之類)XD。 乾蝦乾蝦:)。