实现 用户名或邮箱等 任意一个字段均可登录

在需求中,我们经常会遇到要求使用 邮箱 / 用户名 / 手机号 等 均可以登录的情况,但是 Laravel 自带的用户认证系统中是不能实现这个需求的,默认下,我们要么使用邮箱,要么使用用户名,不能同时使用 :

class LoginController extends Controller
{
        public function username(){

            // return "username" ; 
            return "email" ;
        }
}

既然原生的不能实现,那么我们就自己手动修改 LoginController 以实现我们的需求 。

  1. 首先写登录表单(只有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>
  2. 修改 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 协议》,转载必须注明作者和本文链接
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
讨论数量: 1

其实可以用正则判断是否有 @ 和 . 应该就是邮箱了,一般用户名不会有 . 和 @ 符号的吧

6年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!