在需求中,我們經常會遇到要求使用 郵箱 / 使用者名稱 / 手機號 等 均可以登入的情況,但是 Laravel 自帶的使用者認證系統中是不能實現這個需求的,預設下,我們要麼使用郵箱,要麼使用使用者名稱,不能同時使用 :
class LoginController extends Controller
{
public function username(){
// return "username" ;
return "email" ;
}
}
既然原生的不能實現,那麼我們就自己手動修改 LoginController 以實現我們的需求 。
- 首先寫登入表單(只有2個欄位 name 和 password):
<form action="{{ url('/login') }}" method="post" > {{ csrf_field() }} <input name="name" type="text" placeholder="使用者名稱/郵箱" /> <input name="password" type="password" placeholder="密碼" /> <button type="submit">登入</button> </form>
-
修改 LoginController ( 為簡短,省略部分沒用的程式碼 ) :
class LoginController extends Controller { use AuthenticatesUsers; // 依賴注入 Request 並儲存 protected $request; public function __construct(Request $request) { $this->request = $request; $this->middleware('guest')->except('logout'); } // 判斷使用者名稱是否是郵箱 protected function nameIsEmail() { if (strpos($this->request->post('name'), '@') > 0) { return true; } return false; } // 覆蓋 AuthenticatesUsers validateLogin 方法 // 在此可以完成我們要做的驗證 protected function validateLogin(Request $request) { if ($this->nameIsEmail()) { $this->validate($request, [ 'name' => 'required|string|email:users,email', 'password' => 'required|string', ]); } $this->validate($request, [ 'name' => 'required|string', 'password' => 'required|string', ]); } // 覆蓋 AuthenticatesUsers credentials 方法 // 注意這裡的返回值是陣列,這個陣列中的資料將用來和資料庫做欄位對比 protected function credentials(Request $request) { if ($this->nameIsEmail()) { return array( 'email' => $this->request->post('name'), // 注意下標為 email,對應資料表中的 email 欄位 'password' => $this->request->post('password') ); } return array( 'name' => $this->request->post('name'), // 注意下標為 name , 對應資料表中的 name 欄位 'password' => $this->request->post('password') ); } }
3、完成
但是有的人可能會想:如果使用者名稱中剛好有 @ 字元怎麼辦?
這個簡單,我們可以限制註冊的使用者名稱欄位只能為數字+字母+下劃線等等,禁止使用者名稱有 @ 等非法字元
小結:
第一次寫,有不對的地方望大佬指教,謝謝大家 。
透過這種方式我已經實現,但是不會上傳截圖 。還有,以上我只是實現了 使用者名稱和郵箱 的登入,手機號等登入方法和以上一樣,只需要再加些驗證和判斷就行了。
總結:就是在控制器中去覆蓋 AuthenticatesUsers trait 的 validateLogin 方法 和 credentials方法 ,如果大家對這些方法不清楚,建議好好閱讀原始碼。
本作品採用《CC 協議》,轉載必須註明作者和本文連結