[5.3] Login via email OR username

Published 1 year ago by 2Pr3cise

Hi everyone,

In my application, I want to be able to login in either with my username or my email address (thus, I added a username column to the schema).

I tried to set up the LoginController like this, which did not work ...

public function username()
{
    $login = request('login');
    return filter_var( $login, FILTER_VALIDATE_EMAIL ) ? 'email' : 'username';
}

protected function validateLogin(Request $request)
{
    $this->validate($request, [
        'login' => 'required', 'password' => 'required',
    ]);
}

My login form contains the inputs login (which is the email or the username) and a password input.

... I think I need to implement something more. Can you help me?

Thanks in advance!!

Best Answer (As Selected By 2Pr3cise)
BradHe

I made it in Laravel 5.3.4, Can you try to read Chinese article? link:

http://river0314.lofter.com/post/1d03f335_c2a1605

or i translate one way to make it: In /app/Controllers/Auth/LoginController add 2 functions, copy from \vendor\laravel\framework\src\Illuminate\Foundation\Auth\ AuthenticatesUsers.php , they are credentials() and username() functions,they edit them like this:

/**
 *  add function credentials and username
 *  添加这两个修改之后的方法,为了兼容email和mobile 两个字段作为账号登录
 */
protected function credentials(Request $request)
{
    $field = filter_var($request->input($this->username()), FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
    $request->merge([$field => $request->input($this->username())]);
    return $request->only($field, 'password');
}

/** 这个是声明账户登录的name值 */
public function username()
{
    return 'login';
}

besides, edit login.blade.php like this: /** login */ Email/UserName

                        <div class="col-md-6">
                            <input id="email" type="text" class="form-control" name="login" value="{{ old('login') }}" autofocus>
                            @if ($errors->has('login'))
                                <span class="help-block">
                                    <strong>{{ $errors->first('login') }}</strong>
                                </span>
                            @endif
                        </div>
                    </div>
                            

so, you can use email or username to login.

so, you don't need to edit AuthenticatesUsers.php. Forgive my poor English

2Pr3cise

Anyone?

BradHe
BradHe
1 year ago (6,510 XP)

I made it in Laravel 5.3.4, Can you try to read Chinese article? link:

http://river0314.lofter.com/post/1d03f335_c2a1605

or i translate one way to make it: In /app/Controllers/Auth/LoginController add 2 functions, copy from \vendor\laravel\framework\src\Illuminate\Foundation\Auth\ AuthenticatesUsers.php , they are credentials() and username() functions,they edit them like this:

/**
 *  add function credentials and username
 *  添加这两个修改之后的方法,为了兼容email和mobile 两个字段作为账号登录
 */
protected function credentials(Request $request)
{
    $field = filter_var($request->input($this->username()), FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
    $request->merge([$field => $request->input($this->username())]);
    return $request->only($field, 'password');
}

/** 这个是声明账户登录的name值 */
public function username()
{
    return 'login';
}

besides, edit login.blade.php like this: /** login */ Email/UserName

                        <div class="col-md-6">
                            <input id="email" type="text" class="form-control" name="login" value="{{ old('login') }}" autofocus>
                            @if ($errors->has('login'))
                                <span class="help-block">
                                    <strong>{{ $errors->first('login') }}</strong>
                                </span>
                            @endif
                        </div>
                    </div>
                            

so, you can use email or username to login.

so, you don't need to edit AuthenticatesUsers.php. Forgive my poor English

2Pr3cise

Thanks for sharing!

chriz77
chriz77
1 year ago (14,110 XP)

Any ideas to do this in 5.3 w/out changing files in the vendor folder?

cbgscience

Here is how you do it in Laravel 5.4:

In the LoginController.php file, add the following functions:

 /**
 * Attempt to log the user into the application.
 *
 * @param  \Illuminate\Http\Request  $request
 * @return bool
 */
protected function attemptLogin(Request $request)
{
    
    //check if attempt is successful using the email field
    $attempt_with_email = $this->guard()->attempt($this->credentials($request), $request->has('remember'));

    if(empty($attempt_with_email))
    {
        //attempt failed with email, so lets try to use the user_name field instead
        //we will need to replace the email field with the user_name field in the request array
        $request->request->add(['user_name' => $request->email]);
        
        $request->request->remove('email');
    
        //attempt to log in with user_name
        return $this->guard()->attempt(
            $this->credentials_user_name($request), $request->has('remember')
        );
    }

    return $attempt_with_email;
}

//change credentials to use the field user_name instead of the default email
protected function credentials_user_name(Request $request)
{
    return $request->only('user_name', 'password');
}

bunnypro

if you are doing this, make sure the username that inputed when registering is not an email.

arabsight

just override the username method:

public function username()
{
    $login = request()->input('login');
    $field = filter_var($login, FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
    request()->merge([$field => $login]);
    return $field;
}

Please sign in or create an account to participate in this conversation.