In this article, we will customize laravel default authentication functionality to login with both email or username. We all know that laravel provide a nice basic authentication function out of the box where a user can register and login using email. We will take it further step adding a login with username also.
We will start with the fresh laravel installation project. Before starting, I suppose that you have already set up your database.
So, let’s get started.
Customizing Migration
First of all, we need to create a field to store our username in the database. So, let’s change our default laravel migration file for users table. Open your create_users_table.php and add a username field of type string and unique.
// ./database/migrations/....create_users_table.php public function up() { Schema::create('users', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('username')->nullable()->unique(); $table->string('email')->unique(); $table->string('password'); $table->rememberToken(); $table->timestamps(); }); }
After changing migration file, we need to migrate it to create tables in database. Run the command below:
php artisan migrate
We have our table ready with username field. Now, it needs to be fillable to store data. Thus, to make fillable, add username
field to User
model.
Thus, your User
model’s fillable code looks like below:
// ./app/User.php ... protected $fillable = [ 'name', 'email', 'password', 'username', ]; ...
Create Authentication Scaffolding
We will create laravel default authentication scaffolding with the help of following command:
php artisan make:auth
I believe you are familiar with this command. It will create some folders and files in our project.
Edit Register Blade
Now, we need to add a input field to get username from user. It will be of type text
. We will make username required
while registration. I have replicated other div for nice appearance and displaying error message. So, our final register blade looks as below:
@extends('layouts.app') @section('content')@endsection{{ __('Register') }}
Thus, our register form looks like this screenshot
Edit RegisterController
We need to change our RegisterController
to validate and store username in our database. Our final RegisterController looks like below:
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, [ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'username' => 'required|string|max:20|unique:users', // added for username validation 'password' => 'required|string|min:6|confirmed', ]); } /** * Create a new user instance after a valid registration. * * @param array $data * @return \App\User */ protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'username' => $data['username'], // added for storing username 'password' => Hash::make($data['password']), ]); } }
Edit Login Blade
Laravel default authentication system allows us an only email in the login field. We will change this to text because we can input both email or username.
Just change the input type of email address
From
To
Edit Login Controller
Now, we finally need to modify our LoginController to accept both email or username. For this, we need to modify credentials
method so that during authentication, it check whether email or username.
AuthenticatesUsers
trait for login which defines different methods. If you need to orverride these methods by Just writing a function of the same name in the Controller, and it will be used in preference to the one in the trait.
To check whether input data is email or username, we will use below code:
$field = filter_var($request->get($this->username()), FILTER_VALIDATE_EMAIL) ? $this->username() : 'username';
Here, filter_var($request->get($this->username()), FILTER_VALIDATE_EMAIL)
will check if input is valid email address or not. Using ternary operator, we will asign email
if it is valid email address or username on fail.
So, our final LoginController
looks like below after modification:
middleware('guest')->except('logout'); } /** * We are overriding AuthenticatesUsers trait to check * whether input field is email or username * @param Request $request [input data] * @return array credentials */ protected function credentials(Request $request) { $field = filter_var($request->get($this->username()), FILTER_VALIDATE_EMAIL) ? $this->username() : 'username'; return [ $field => $request->get($this->username()), 'password' => $request->password, ]; } }
Testing
We have done all necessary steps to login via email or username. Let’s test our project. Run the development server with command:
php artisan serve
Navigate to the route http://127.0.0.1:8000/register
register with all details.
Now, navigate to route http://127.0.0.1:8000/login
and enter your username instead of email. You can login using both username or email address.
Conclusion
That is all about customizing laravel default authentication for login with username or email. If you want to read a nice article about login with Facebook, Twitter, Google, LinkedIn, GitHub and Bitbucket, you can read this article: “Social Login in Laravel using Socialite“.
Thank you for reading this article. If you have any question or feedback, please drop a comment below.