Building Your Own Laravel Authentication Posted on December 30, 2015

Normally when building a Laravel Application, we can get away with just using the regular Authentication Controllers that come along with Laravel 5.1 (however, they have been removed in Laravel 5.2 and can be brought back with an artisan command).

Once in awhile our clients don't want to use the regular email as the username, sometimes they may want to use an actual name or username instead of the email. A quick and easy way to do this is to create a new login command to handle the information (we would also update the create user command as well or any other functions that we need to update).

Login controller

Let's create a new controller called LoginController. The easiest way to do this is to run the following artisan command (or create a new file and copy the following code into it).

<?php namespace App\Http\Controllers;

use Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Redirect;

class LoginController extends Controller {

    public function __construct()
    {
        $this->middleware('guest', ['except' => ['logout']]);
    }

    public function logout()
    {
    }

    public function login()
    {
    }

    public function authenticate(Request $request)
    {
    }

}

Now that we have created our controller and added some stubs into it let's start taking a look at the code we are going to add and how it will all work together.

Controller constructor

You will see that in our __construct function we are controlling how our users can access the functions inside this controller. We are allowing guests to access our controller EXCEPT for the logout method. Since the user needs to be logged in, there is no use in trying to log someone out who isn't logged in.

Login

When presenting the user with the login form we want to redirect the user to our login() method. This method is pretty light as all we are going to be doing is showing our view.

public function login()
{
    return view('user.login');
}

Examining the code above you can see that we are returning a view for the html template found in the location /resources/views/user/login.blade.php

This is all our login function needs to do. Our view is pretty simple as well, the only difference between it and the original is we are asking for a username instead of an email address. You can view the blade file at https://gist.github.com/tutelagesystems/a626689a98787af59430

Authenticating the user

When the user presses login we need to try to authenticate them. If we are looking at the Laravel Documentation you can see we will be using the Auth::attempt function. This function accepts an array of key value pairs to test on the database. Normally Laravel uses this with then email and password but we are going to change it to use username and password instead.

Editing our authenticate stub let's grab the user's input from our form and attempt to authenticate them.

public function authenticate(Request $request)
{
    // setup rules for validation of user input
    $rules = [
        'username' => 'required',
        'password' => 'required'
    ];

    // run validation, if this does not pass Laravel will redirect back with input and errors
    $this->validate($request, $rules);

    // attempt to authenticate the user
    if(Auth::attempt(['username' => $request->input('username'), 'password' => $request->input('password')]))
    {
        // the information was correct
        // the user is already logged in from the Auth::attempt call, so we really don't need to do anything here
    }
    else
    {
        // the attempt was not correct, lets redirect back with input and an error
        return Redirect::back()->withInput()->withErrors(['The user information is invalid']);
    }

}

The Auth::attempt not only checks our username and password but if it is true, then it creates the user's authenticated session for us automatically. How neat is that? Next we will finish the stub on our logout() method.

Logging out the user

To log the user out it is extremely simple and straight forward. We could even use the AuthController that comes with Laravel to do it, but since we are rolling our own, lets finish this up but changing the stub.

public function logout()
{
    Auth::logout();

    // send the user somewhere
    return Redirect::route('home'); // the route 'home' would need to be defined in our routes file.
}

The only other thing will be to add the routes into our file.

Authentication routes

Since I want all our authentication to start with /auth I will add a prefix into our routes. Not only does this make our url's nicer, but keeps our code cleaner.

Route::group(['prefix' => 'auth'], function() {
    Route::get('/login', array(
        'as'   => 'auth.login',
        'uses' => 'LoginController@login')
    );
    Route::post('/authenticate', array(
        'as'   => 'auth.authenticate',
        'uses' => 'LoginController@authenticate')
    );
    Route::get('/logout', array(
        'as'   => 'auth.logout',
        'uses' => 'LoginController@logout')
    );
});

Now you are left with hooking up the routes into your html (blade file). Since we are using named routes you can call them like

<a href="{{ URL::route('auth.login') }}">User Login</a>

Well that wraps up everything, if you have questions please post them in the comments below.

Share this post