Simple user authentication in Laravel 4


With the recent release of Laravel 4, PHP developers have at their disposal one of the finest frameworks for application development. As with all new frameworks, it is always good to write some quick code to get a feel for the underlying architecture. The following post shows a simple authentication application using Laravel.

Installing Laravel 4

Laravel 4 uses Composer for dependency management as the framework itself depends on a number of external packages to function correctly. Each of the components used by Laravel 4 is available individually on the Illuminate GitHub repository. Laravel 4 ties together the Illuminate components to create the framework. Some of the other packages Laravel 4 uses are – Doctrine, Monolog, Symfony, Predis.

If you are new to Composer you can read all about it here. Windows users have a nice installable package available.

Our application will only have a login form and a simple admin page that requires authentication. Initially we will code the entire controller login in the route itself.

Database and User table

First you need to create a database for your Laravel application and update the app/config/database.php file with the database credentials.

'default' => 'mysql',
 
'mysql' => array(
			'driver'    => 'mysql',
			'host'      => 'localhost',
			'database'  => 'your_database_name',
			'username'  => 'your_database_username',
			'password'  => 'your_database_password',
			'charset'   => 'utf8',
			'collation' => 'utf8_unicode_ci',
			'prefix'    => '',
		),

Next insert the following ‘user’ table in your new database. The SQL also includes a sample row with a username an password.

CREATE TABLE IF NOT EXISTS `users` (
  `id` int(10) unsigned NOT NULL auto_increment,
  `username` varchar(128) collate utf8_unicode_ci NOT NULL,
  `password` varchar(64) collate utf8_unicode_ci NOT NULL,
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
 
INSERT INTO `users` (`id`, `username`, `password`) VALUES
  (1, 'Laravel', '$2y$08$XmdaKIivCTTdLwToVCii4Obk.699DQTLFAbw62wcJToRqL2Q4PiA2');

Next we need to configure the app/config/auth.php settings. This contains some standard authentication options for your application. Note that the user authentication table is called ‘users’, same as the table name above, but you can change that to anything you like as long you also change the corresponding table name in the database. Also we will be using the ‘database’ driver instead of ‘eloquent’.

<?php
 
return array(
 
	/*
	|--------------------------------------------------------------------------
	| Default Authentication Driver
	|--------------------------------------------------------------------------
	|
	| This option controls the authentication driver that will be utilized.
	| This drivers manages the retrieval and authentication of the users
	| attempting to get access to protected areas of your application.
	|
	| Supported: "database", "eloquent"
	|
	*/
 
	'driver' => 'database',
 
	/*
	|--------------------------------------------------------------------------
	| Authentication Model
	|--------------------------------------------------------------------------
	|
	| When using the "Eloquent" authentication driver, we need to know which
	| Eloquent model should be used to retrieve your users. Of course, it
	| is often just the "User" model but you may use whatever you like.
	|
	*/
 
	'model' => 'User',
 
	/*
	|--------------------------------------------------------------------------
	| Authentication Table
	|--------------------------------------------------------------------------
	|
	| When using the "Database" authentication driver, we need to know which
	| table should be used to retrieve your users. We have chosen a basic
	| default value but you may easily change it to any table you like.
	|
	*/
 
	'table' => 'users',
 
	/*
	|--------------------------------------------------------------------------
	| Password Reminder Settings
	|--------------------------------------------------------------------------
	|
	| Here you may set the settings for password reminders, including a view
	| that should be used as your password reminder e-mail. You will also
	| be able to set the name of the table that holds the reset tokens.
	|
	*/
 
	'reminder' => array(
 
		'email' => 'emails.auth.reminder', 'table' => 'password_reminders',
 
	),
 
);

The Login form

First we will design a simple login form view to be displayed for the login action.
Laravel comes with the blade templating engine, but for this post we will go with the standard HTML markup. If our domain is mysite.com, the below login form will be visible at mysite.com/login. Upload the loginForm.php file to the app/views directory.

<!--
app/views/loginForm.php
-->
<!DOCTYPE HTML>
<html>
<head>
<title>Simple Login Form in Laravel</title>
<meta charset="UTF-8" />
<?php 
    echo HTML::style('css/reset.css'); 
    echo HTML::style('css/structure.css');
?>
</head>
<body>
<?php echo Form::open(array('url' => '/login', 'class' => 'box login')); ?>
<fieldset class="boxBody">
  <label>Username</label>
  <input type="text" tabindex="1" name="username" required>
  <label>
  <a href="#" class="rLink" tabindex="5">Forget your password?</a>Password
  </label>
  <input type="password" name="password" tabindex="2" required>
</fieldset>
<footer>
  <label><input type="checkbox" name="persist" tabindex="3">Remember me</label>
  <input type="submit" class="btnLogin" value="Login" tabindex="4">
</footer>
</form>
<footer id="main">
</footer>
</body>
</html>

We import the stylesheets using the HTML helper class. The css files are stored in the public/css directory. Next we open the form using the Form::open method. The Form::open method can take additional parameters. Here we are specifying that the form should be posted to the /login url and also that the css ‘box’ and ‘login’ classes be applied to the form.

Form::open(array('url' => '/login', 'class' => 'box login'));

The route for the above login view is given below. This will display the login form when a GET request is made to the mysite.com/login url.

#app/routes.php

Route::get('login', function()
{
    return View::make('loginForm');
});

The admin page

Our applications admin view is a simple HTML page that displays a message along with a logout link. The admin page is visible at mysite.com/admin. At this point we can access the admin page without authentication. Later we will add the code to make sure that only authenticated users can view this page.

<!--
app/views/adminPage.php
-->
<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>Admin</title>
</head>
<body>
<h1>Hello Admin!</h1>
<a href="/logout">Logout</a>
</body>
</html>

The route for the above admin view is given below.

#app/routes.php

Route::get('admin', function()
{
    return View::make('adminPage');
});

User Authentication

Next we will define the authentication logic in the route itself rather than a separate controller. Although for smaller applications this will work fine, for larger ones it is advisable to define a separate controller. As our login form will be submitted using the POST method, we need to define our authentication logic in a POST route. Note that the logic in routes are defined using anonymous functions.

#app/routes.php

Route::post('login', function()
{
        /* Get the login form data using the 'Input' class */
        $userdata = array(
            'username' => Input::get('username'),
            'password' => Input::get('password')
        );
 
        /* Try to authenticate the credentials */
        if(Auth::attempt($userdata)) 
        {
            // we are now logged in, go to admin
            return Redirect::to('admin');
        }
        else
        {
            return Redirect::to('login');
        }
});

At this point whenever the user is correctly authenticated they are redirected to the ‘admin’ page. However at present we can also view the ‘admin’ page without any authentication.

Completing the app

Lastly we will define a route for the home page that will just display a simple text message.

#app/routes.php
Route::get('/', function()
{
    return "Welcome Home";
});

Restricting ‘admin’ page access

We can easily restrict ‘admin’ page access in our routes using filters. Route filters provide a convenient way of limiting access to a given route, which is useful for creating pages of your site which require authentication. There are several filters included in the Laravel framework, an auth filter, auth.basic filter, a guest filter, and a csrf filter. These are located in the app/filters.php file. We can also define our very own custom filters. In our example we will use the in-built ‘auth’ filter. This instrcuts the route to apply the auth filter before displaying the
‘admin’ page.

Route::get('admin', array('before' => 'auth', function()
{
    return View::make('adminPage');
}));

You can find the ‘auth’ filter defined in app/filters.php.

Route::filter('auth', function()
{
     if (Auth::guest()) return Redirect::guest('login');
});

Laravel filters provide a powerful and flexible way to process requests and will help you immensely while developing complex request scenarios.

To complete the application here is the logout route.

Route::get('logout', function()
{
    Auth::logout();
    return Redirect::to('login');
});

The complete routes.php is shown below.

<?php
 
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/
 
Route::get('/', function()
{
    return "Welcome Home";
});
 
Route::get('admin', array('before' => 'auth', function()
{
    return View::make('adminPage');
}));
 
Route::get('login', function()
{
    return View::make('loginForm');
});
 
Route::get('logout', function()
{
    Auth::logout();
    return Redirect::to('login');
});
 
Route::post('login', function()
{
    $userdata = array(
            'username' => Input::get('username'),
            'password' => Input::get('password')
        );
 
    if(Auth::attempt($userdata))
    {
        // we are now logged in, go to admin
        return Redirect::to('admin');
    }
    else
    {
        return Redirect::to('login');
    }
});

Moving the authentication logic to a controller

In the above scenario we have put the authentication login in the route itself. No harm there, but for more involved code it is better if we move the authentication part to its own controller. Create a new file ‘UserLogin.php’ in app/controllers and copy the following code.

<?php
 
class UserLogin extends BaseController {
 
    public function user()
    {
        // get POST data
        $userdata = array(
            'username' => Input::get('username'),
            'password' => Input::get('password')
        );
 
        if(Auth::attempt($userdata))
        {
            // we are now logged in, go to admin
            return Redirect::to('admin');
        }
        else
        {
            return Redirect::to('login');
        }
    }
}

In the routes.php file define the ‘login’ route as below. The second parameter, ‘UserLogin@user’, consists of the controller name followed by the method we want to run.

Route::post('login', 'UserLogin@user');

As you can see it is very easy to use a controller within a route. This post has only scratched the surface with what Laravel has to offer. In coming posts we will look into various features mentioned here in detail. I’ve included the css files required for the login form below. Copy them to your Laravel /public/css folder.

Download Code files
Downloads : 1611 / File size : 3.1 kB

This site is a digital habitat of Sameer Borate, a freelance web developer working in PHP, MySQL and WordPress. I also provide web scraping services, website design and development and integration of various Open Source API's. Contact me at metapix[at]gmail.com for any new project requirements and price quotes.

10 Responses

1

PHPDeveloper.org: Sameer Borate: Simple user authentication in Laravel 4

June 17th, 2013 at 12:26 pm

[...] Borate has a new post today showing how you can do simple user authentication in a Laravel 4-based application using the built-in Auth [...]

2

dordije

June 30th, 2013 at 6:29 am

Thanks for helpful post !

Unfortunatelly in reality we cant allways follow framework assumptions.

Suppose we have users table with name UserTable and it have username and password fields named UserName and PassValue. What and where I must change in your example to work with that table ? I tried but stacked with errors Udefined index:password or Undefined index:username.

I searched other login examples but all of them use users table with username and password fileds.

Thanks in advance.

sameer

July 1st, 2013 at 4:44 am

You can change the users table name in the ‘app/config/auth.php’ file as mentioned in the post.

4

dordije

July 1st, 2013 at 9:46 am

Sameer, I changed table name in auth.php. Also driver is ‘database’, not ‘eloguent’.

As in my table I do not have fields named ‘username’ and ‘password’ I also changed field names in file app\controllers\UserLogin.php.

After that I receiver error Undefined index:password from C:\xampp\htdocs\laravel4\vendor\laravel\framework\src\Illuminate\Auth\DatabaseUserProvider.php . It is somethere deep in framework.

It looks like I must have fields named ‘username’ and ‘password’ in my table, or it can be overcomed in some other way ?

sameer

July 1st, 2013 at 8:26 pm

Laravel expects the password field to be named ‘password’,while you can name the username field to anything you want. Of course you could extend the auth model to accept your custom fields, but that would be a unnecessary hassle for a small issue.

6

william

August 8th, 2013 at 1:45 pm

you just have to use a protected $guarded = array(“whatever”) property in your model. in the credentals you still look for password but laravel will chek the whatever field

7

steve

August 9th, 2013 at 9:19 am

Thanks for the article.

Could you tell me what the unhashed password is ?
INSERT INTO `users` (`id`, `username`, `password`) VALUES
(1, ‘Laravel’, ‘$2y$08$XmdaKIivCTTdLwToVCii4Obk.699DQTLFAbw62wcJToRqL2Q4PiA2′);

Many Thanks

8

Hal

October 25th, 2013 at 6:03 am

This is nice… but you didn’t give the actual password nor how to create a new admin user.

9

duy hoang

May 10th, 2014 at 1:05 pm

Update password in your database to : $2y$10$6GJRcXsqtXZkss5zxCky6uhCCNtxrUiih2KeQJomc9V2R1rDqvGGW

New password is : admin
Sorry for my english :D
//Generate password by method : Hash::make(‘myPassword’);

10

Dan

May 29th, 2014 at 3:22 am

Hey All,
i have this issue…
http://wefixbugs.com/blog.php?askid=5632
please help

Your thoughts