X
    Categories: Laravel

Login with username or email or mobile using laravel 5.5

Hi, In this tutorial we are going to see how to do a login with username or email or mobile. Laravel by default have its own auth functions Which will used to login using email id.  Sometimes you need to login with username or email or some other fields also. For this you need to make some changes in login controller. Lets see here.

Step 1 : Install Laravel application

Step 2 : Run php artisan make:auth to install default laravel auth scaffolding

It will create Auth routes, Controllers, and Views.

Step 3 : Run migration

By default laravel user migration table contains email, password and remember tokens. You need to add username and mobile to your users table migration and run php artisan migrate. It will create all migration tables.

<?php

use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateUsersTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('users', function (Blueprint $table) {
            $table->increments('id');
            $table->string('username', 15)->nullable();
            $table->string('email')->unique();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('users');
    }
}

Step 4

Go to registration page : http://www.example.com/register. Default registration page does’t contain username and password. So add user required fields here to user submit a data.


My register.balde.php

@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Register</div>
                <div class="panel-body">
                    <form class="form-horizontal" role="form" method="POST" action="{{ route('register') }}">
                        {{ csrf_field() }}

                        <div class="form-group{{ $errors->has('username') ? ' has-error' : '' }}">
                            <label >
Step 5 : Change RegisterController to register a required fields to user table. App/Http/Controllers/Auth/RegisterController.php
<?php

namespace App\Http\Controllers\Auth;

use App\User;
use App\UserProfile;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;

class RegisterController extends Controller
{
    /*
    |--------------------------------------------------------------------------
    | Register Controller
    |--------------------------------------------------------------------------
    |
    | This controller handles the registration of new users as well as their
    | validation and creation. By default this controller uses a trait to
    | provide this functionality without requiring any additional code.
    |
    */

    use RegistersUsers;

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

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

    /**
     * Get a validator for an incoming registration request.
     *
     * @param  array  $data
     * @return \Illuminate\Contracts\Validation\Validator
     */
    protected function validator(array $data)
    {
        return Validator::make($data, [
            'username' => 'required|string|alpha_dash|username_password_match|banned_words|min:8|max:12|unique:users',
            'email' => 'required|string|email|max:255|unique:users',
            'password' => 'required|password_validation|string|min:8|max:12|confirmed',
            'mobile' => 'required|numeric|unique:user_profiles|phone',
        ]);
    }

   
    /**
     * Create a new user instance after a valid registration.
     *
     * @param  array  $data
     * @return User
     */
    protected function create(array $data)
    {
        $user =  User::create([
            'username' => $data['username'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
        
        if($user && $data['mobile'] != ''){
            $this->registerMobileNumber($user->id, $data['mobile']);
        }
        return $user;
    }

    public function registerMobileNumber($userId, $mobile) {
        try {
            $userProfile = new UserProfile;
            $userProfile->user_id = $userId;
            $userProfile->mobile = $mobile;
            $userProfile->save();
        } catch (Exception $e) {
            
        }
    }
}

Step 6 : Change you LoginController to login as flexible

By default LoginController does't contain any login check functionalities. It will handle by laravel auth scaffoldings. So we need to overwrite a login controller to do a trick.

Default LoginController.php

<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
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 = '/home';
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('guest')->except('logout');
    }
}

You can write a login() function to overwrite default login logic. My customise logincontroller

<?php

namespace App\Http\Controllers\Auth;

use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Http\Request ;
use Auth;
use Session;
use App\UserProfile;
use App\User;

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 function authenticated(Request $request, $user)
    {
        return redirect('/home');
    }

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

    public function login(Request $request)
    {
        $this->validate($request, [
                'email'    => 'required',
                'password' => 'required',
            ]);
        
        //Store Email field Value
        $loginValue = $request->input('email');
        
        //Get Login Type
        $login_type = $this->getLoginType( $loginValue);

        //Change request type based on user input
        $request->merge([
            $login_type => $loginValue
        ]);
        
        //Check Credentials and redirect
        if (Auth::attempt($request->only($login_type, 'password'))) {
            return redirect()->intended($this->redirectPath());
        } 
         return redirect()->back()->withInput()->withErrors([ 'email' => "These credentials do not match our records." ]);
    } 

    //Check user input type
    public function getLoginType($loginValue) {
        return filter_var($loginValue, FILTER_VALIDATE_EMAIL ) 
            ? 'email' 
            : ( (preg_match('%^(?:(?:\(?(?:00|\+)([1-4]\d\d|[1-9]\d?)\)?)?[\-\.\ \\\/]?)?((?:\(?\d{1,}\)?[\-\.\ \\\/]?){0,})(?:[\-\.\ \\\/]?(?:#|ext\.?|extension|x)[\-\.\ \\\/]?(\d+))?$%i', $loginValue)) ? 'mobile' : 'username' );
    }
}

Here I will collect user input email and check the following condition in getLoginType() function

1. Check given user input is email. If yes loginType should be 'email'
2. Check given user input is mobile no. If yes loginType should be 'mobile'
3. Otherwise username

and merge user logintype in post request. then collect only logintype input and password input to auth::check. It will check the user credentials and do the trick.

Output

Thanks for reading this article. Hope it will help someone.

Marimuthu:

View Comments

  • This saves me a lot of work. Btw, sir you have a github/source code for this? It's hard to read the code and I'm still learning laravel. Thanks :)

    • Thanks for your feedback. Sorry @junienegentien:disqus . I dont have github code. Give me your email id. I will share you my code. Thanks:)