实现 用户名或邮箱等 任意一个字段均可登录
在需求中,我们经常会遇到要求使用 邮箱 / 用户名 / 手机号 等 均可以登录的情况,但是 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 协议》,转载必须注明作者和本文链接
其实可以用正则判断是否有 @ 和 . 应该就是邮箱了,一般用户名不会有 . 和 @ 符号的吧