Laravel 实现用户名 + 邮箱 + 手机号登录

视图中我将待验证字段命名为 account

resources/views/auth/login.blade.php

<form action="{{ route('login') }}" method="post">
    {{ csrf_field() }}

    {{--账号--}}
        <div class="form-group has-feedback">
            <input type="text" name="account" class="form-control" placeholder="用户名/邮箱/手机号">
            <span class="glyphicon glyphicon-user form-control-feedback"></span>
            @if ($errors->has('account'))
                <span class="help-block" style="color: #d73925;">
                    <strong>{{ $errors->first('account') }}</strong>
                </span>
            @endif
    </div>
.
.
.

接下来在 LoginController.php 重写 AuthenticatesUsers trait 中的 attemptLogin()validateLogin()username()、三个方法。

  • attemptLogin() 方法:

return $this->guard()->attempt(
    $this->credentials($request), $request->filled('remember')
);

替换为

return collect(['username', 'email', 'phone'])->contains(function ($value) use ($request) {
    $account = $request->get($this->username());
    $password = $request->get('password');
    return $this->guard()->attempt([$value => $account, 'password' => $password], $request->filled('remember'));
});
  • validateLogin() 方法:

主要是将 $this->username() 改为中文。当然你还可以添加自己的验证规则。

protected function validateLogin(Request $request)
{
    $this->validate($request, [
        $this->username() => 'required|string',
        'password' => 'required|string',
        'captcha' => 'required|captcha',
    ],[
        'captcha.required' => ':attribute 不能为空',
        'captcha.captcha' => '请输入正确的 :attribute',
    ],[
        $this->username() => '账号',
        'captcha' => '验证码',
    ]);
}

username() 方法:

不用说,将返回字段改为 account

public function username()
{
    return 'account';
}

完整代码:

app/Http/Controllers/Auth/LoginController.php

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

class LoginController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Login Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles authenticating users for the application and
    | redirecting them to your home screen. The controller uses a trait
    | to conveniently provide its functionality to your applications.
    |
    */

    use AuthenticatesUsers;

    /**
     * Where to redirect users after login.
     *
     * @var string
     */
    protected $redirectTo = '/';

    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }

   /**
     * Attempt to log the user into the application.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return bool
     */
    protected function attemptLogin(Request $request)
    {
        return collect(['username', 'email', 'phone'])->contains(function ($value) use ($request) {
            $account = $request->get($this->username());
            $password = $request->get('password');
            return $this->guard()->attempt([$value => $account, 'password' => $password], $request->filled('remember'));
        });
    }

    /**
     * 登录验证.
     *
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    protected function validateLogin(Request $request)
    {
        $this->validate($request, [
            $this->username() => 'required|string',
            'password' => 'required|string',
            'captcha' => 'required|captcha',
        ],[
            'captcha.required' => ':attribute 不能为空',
            'captcha.captcha' => '请输入正确的 :attribute',
        ],[
            $this->username() => '账号',
            'captcha' => '验证码',
        ]);
    }

    public function username()
    {
        return 'account';
    }
}

最后还有一个小问题,拷贝 overtrue/laravel-lang 语言包稍作一个小修改:

$ mkdir resources/lang/zh-CN
$ cp vendor/caouecs/laravel-lang/src/zh-CN/auth.php resources/lang/zh-CN

'failed' => '用户名或密码错误。', 修改为 'failed' => '账号或密码错误。',

resources/lang/zh-CN/auth.php

<?php

return [
    /*
    |--------------------------------------------------------------------------
    | Authentication Language Lines
    |--------------------------------------------------------------------------
    |
    | The following language lines are used during authentication for various
    | messages that we need to display to the user. You are free to modify
    | these language lines according to your application's requirements.
    |
    */

    'failed' => '账号或密码错误。',
    'throttle' => '您的尝试登录次数过多,请 :seconds 秒后再试。',
];

感谢 @BradStevens、@bing8u 指正。

本作品采用《CC 协议》,转载必须注明作者和本文链接
本帖由系统于 5年前 自动加精
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 5
bing8u
    /**
     * 登录认证
     * @param Request $request
     * @return bool
     */
    protected function attemptLogin(Request $request)
    {
        return collect(['name', 'email', 'mobile'])->contains(function ($value) use ($request) {
            $account = $request->get($this->username());
            $password = $request->get('password');
            return $this->guard()->attempt([$value => $account, 'password' => $password], $request->filled('remember'));
        });
    }

使用 collect来重构你的项目。

楼主那套,很早以前就不用了!

5年前 评论
phpervip 4年前
bing8u (作者) 4年前
phpervip 4年前
phpervip 4年前
phpervip 4年前
ThinkQ

很好。

5年前 评论

不错啊。

5年前 评论

如果 用户名 和 手机号 邮箱这个字段的规整差别很大的话,可以改一下 username() 这个方法,给返回正则匹配到的字段值,要是遇到用户名和手机号可以是一种的这种,就不好弄了

5年前 评论

不错不错 :+1: :+1:

5年前 评论
bing8u
    /**
     * 登录认证
     * @param Request $request
     * @return bool
     */
    protected function attemptLogin(Request $request)
    {
        return collect(['name', 'email', 'mobile'])->contains(function ($value) use ($request) {
            $account = $request->get($this->username());
            $password = $request->get('password');
            return $this->guard()->attempt([$value => $account, 'password' => $password], $request->filled('remember'));
        });
    }

使用 collect来重构你的项目。

楼主那套,很早以前就不用了!

5年前 评论
phpervip 4年前
bing8u (作者) 4年前
phpervip 4年前
phpervip 4年前
phpervip 4年前

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