You are on page 1of 9

laravelbook.

com
home
documentation
code
contact
Prev Table of contents Next
Warning: Work in Progress!
This site contains a a few lessons on Laravel 4. It's still in it's early phases. Besides, Laravel 4 itself is a moving target and a few things may have
changed by the time you read this.
I will regularly update the content. Thanks!
User Authentication with Laravel
Almost every web application has some need for authentication. Users of our app need the ability to login and logout. Fortunately, Laravel
provides a clean, simple and unobtrusive password-based authentication class to help you validate user credentials and retrieve information about
the current user of your application.
This chapter will guide you through the process of setting up user logins,
Lets start with a quick scenario of how a typical user authentication process works:
Login
Allow a user to sign in with her/his valid security credentials. The authentication process happens by matching the uniquely
identifiable information such as username, email address and password in the database, allowing the user access to the protected
resources only if the given information matches the stored values successfully. If unsuccessful, the user will be redirected to the
login page again.
Logout Allow the user to sign out and set the authenticated user session to nil.
Access
Restriction
Check the session to see if the current user is logged in. Deny access to protected resources if the user is not authenticated.
Fortunately, Laravel provides a robust implementation in the form of the Auth class. The Auth class has several methods:
Laravel Method Purpose
Auth::check() Returns true if the current user is logged in, false otherwise.
Auth::guest() Returns true if the current user is not logged in (a guest).
Auth::user() Get the currently logged in user.
Auth::attempt(array $credentials = array(),
$remember = false)
Attempt to authenticate a user using the given credentials. The $remember parameter
denotes if the user should be permanently remembered by the application.
Auth::login(UserInterface $user, $remember =
false)
Log a user into the application.
Auth::logout() Log the user out of the application.
What We Are Making
Note: Source code for this demo project is available at the github repository
Setup
1
We will begin by installing Laravel 4 as described in the previous lessons.
Installing Meido HTML and Form Helpers
For our project, we will need a few helper libraries to assist building HTML pages and forms. We will use the Meido HTML and Meido Form
libraries. These two libraries are port of Laravel 3s HTML and Form helper classes. We will leverage composer to automatically install these
libraries for us. Open up the composer.json file (in your Laravel app folder) and add the strings "meido/form": "1.0.*" and "meido/html":
"1.0.*" to the require section. Heres what the relevant section will look like:
: {
"illuminate/foundation": ,
"meido/form": ,
"meido/html":
},
Execute the command composer update from the terminal and let composer install all the dependencies for us.
Now, well need to let Laravel to acknowledge these helper libraries. Open up the app/config/app.php file and add the following lines to the
providers section:
,
,
So that the providers section will look like the following:
=> array(
...
,
,
We will also need to add the following line to the aliases section of the same file:
=> ,
=> ,
So that the aliases section will look like the following:
=> array(
...
=> ,
=> ,
Database Setup
We will begin by creating a new database named laravel_auth in our MySql server. We are going to update our app/config/database.php
accordingly:
=> ,
=> array(
=> array(
=> ,
=> ,
=> ,
=> ,
=> ,
=> ,
=> ,
=> ,
),
),
Lets look over the app/config/auth.php file. The authentication configuration contains some basic options to help you get started with
authentication.
<?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"
|
*/
=> ,
/*
|--------------------------------------------------------------------------
| 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.
|
2
*/
=> ,
/*
|--------------------------------------------------------------------------
| 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.
|
*/
=> ,
);
Lets discuss the auth.php settings in detail:
driver
Laravels authentication mechanism is driver based, meaning the responsibility for retrieving users during authentication is delegated to various
drivers. Two are included out of the box: Eloquent and Database.
The Eloquent driver uses the Eloquent ORM to load the users of your application, and is the default authentication driver. The Database driver
uses the Laravel fluent query builder to interact with the database and load your users.
model
When using the Eloquent authentication driver, this option determines the Eloquent model that should be used when loading users.
table
When using the Database authentication drivers, this option determines the database table containing the users of your application.
We are going to use the Eloquent authentication driver for this demo app.
Before we begin, youre going to need to create a new table and a corresponding Eloquent data model to store our user details. We can name this
table and data model whatever we like. To avoid unnecessary tinkering with the app/config/auth.php, we will abide by the default Laravel
convention:
Table name users
Model name User
Lets begin by installing Laravel migrations using the Artisan command-line tool:
$ php artisan migrate:install
Nice! Now we're ready to do some migrating!
Now we will create our users migration table:
$ php artisan migrate:make create_users_table
Migration created successfully!
Lets open up the new migration file in the app/database/migrations folder (mine is named 2012_12_31_075518_create_users_table.php).
Heres how to create a suitable table with the Schema Builder:
public function up()
{
Schema::create( , function($t) {
$t->increments( );
$t->string( , 16);
$t->string( , 64);
$t->timestamps();
});
}
You may add as many additional columns as you wish, but for our demo app this is sufficient.
Heres the rollback code for this migration:
public function down()
{
Schema::drop( );
}
Now, lets apply the migration:
# php artisan migrate
Migrated: 2012_12_31_075518_create_users_table
Now we will create a sample user that we can use to test the authentication process. Create a new file named users.php in the app/database
/seeds folder and copy-paste the following code:
<?php
return array(
array(
3
=> ,
=> Hash::make( )
),
);
In the above snippet, we are populating the username and password columns of our users table. We are using the Laravel Hash class to generate a
hash of the password using highly secure bcrypt algorithm. By storing the hash in the database instead of the plain text password, it offers our
users some extra security. This is a very common practice with web applications.
Lets populate our database with the sample data:
# php artisan db:seed
Seeded table: users (1 records)
Now we have a sample user in the system.
Laravel 4 ships with a pre-generated User model by default in (see app/models/User.php). For our demo app the default model will suffice.
Now, we may begin building the application. Lets contemplate of the site structure in terms of url routes and HTTP verbs:
Url Route Name HTTP Verb Purpose
/ home GET Show home page
/login login GET Show login form
/login N/A POST Log in (authenticate) the user
/profile profile GET Protected resource - only available to logged in users
/logout logout GET Logs out the user
Routes
Lets define the skeleton route handlers in app/routes.php as per our REST-ful schema:
Route::get( , array( => , function () { }));
Route::get( , array( => , function () { }));
Route::post( , function () { });
Route::get( , array( => , function () { }));
Route::get( , array( => , function () { }));
On second thought, we dont want an already logged in user to be able to login. We can prevent that by attaching a before() filter to the login
route:
Route::get( , array( => , function () { }))->before( );
Lets open up the app/filters.php file and implement the guest filter. Laravel comes with a default guest filter, so well only need to slightly
modify the code:
Route::filter( , function()
{
if (Auth::check())
return Redirect::route( )
->with( , );
});
Here we use the Auth::check() method to test if the user is authenticated, and redirect the logged in user back to the home route based on that
test.
Similarly the logout and profile routes should apply only to authenticated users. We need to protect these route from non-authenticated users.
We can attach before() filters to these routes:
Route::get( , array( => , function () { }))->before( );
Route::get( , array( => , function () { }))->before( );
The corresponding auth filter in the app/filters.php file looks like this:
Route::filter( , function()
{
if (Auth::guest())
return Redirect::route( )
->with( , );
});
We use the Auth::guest() method to guard access unless a user is currently logged in using Laravels authentication system. Auth::guest()
returns true only if the current request has no logged in user. As you can see, if no user is logged in, the auth filter returns a redirect to the login
route, overriding the view supplied by our route.
Now, lets begin implementing the routes with closures. Well start with the home route:
Route::get( , array( => , function () {
return View::make( );
}));
The home route simply loads the home.blade.php template from the app/views folder and returns the generated content.
4
We will create a simple CSS stylesheet for our webpages in public/css/style.css. Please refer to the laravel_auth repository for the content of
the stylesheet.
We should strive to abide by good programming practice. Well create a master layout file that will serve as the parent template for all our
sub-templates.
Lets create the file layout.blade.php in the app/views folder:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html>
<head>
<title>Laravel Authentication Demo</title>
{{ HTML::style('/css/style.css') }}
</head>
<body>
<div id= >
<div id= >
<ul>
<li>{{ HTML::route('home', 'Home') }}</li>
@if(Auth::check())
<li>{{ HTML::route('profile', 'Profile' ) }}</li>
<li>{{ HTML::route('logout', 'Logout ('.Auth::user()->username.')') }}</li>
@else
<li>{{ HTML::route('login', 'Login') }}</li>
@endif
</ul>
</div><!-- end nav -->
<!-- check for flash notification message -->
@if(Session::has('flash_notice'))
<div id= >{{ Session::get('flash_notice') }}</div>
@endif
@yield('content')
</div><!-- end container -->
</body>
</html>
We use the Meido HTML helper library to programmatically generate the template. Most of the template is self-explanatory. I would draw your
attention to the nav section. Here we dynamically construct the navigation links based on the authentication status of the user:
@if(Auth::check())
<li>{{ HTML::route( , ) }}</li>
<li>{{ HTML::route( , . Auth::user()->username . ) }}</li>
@else
<li>{{ HTML::route( , ) }}</li>
@endif
We use the Auth::check() method to check if the user is authenticated, and generate separate set of navigation links based on this test.
Heres the home.blade.php partial view template:
@extends('layout')
@section('content')
<h1>Home page</h1>
<p>Current time: {{ date('F j, Y, g:i A') }} </p>
@stop
Nothing fancy here.
Handling Login
Lets now implement the GET /login route:
Route::get( , array( => , function () {
return View::make( );
}))->before( );
The login route simply displays the app/views/login.blade.php template.
Time to create the login form. Heres the code to create the login form:
@extends('layout')
@section('content')
<h1>Login</h1>
<!-- check for login error flash var -->
@if (Session::has('flash_error'))
<div id= >{{ Session::get('flash_error') }}</div>
@endif
{{ Form::open('login', 'POST') }}
<!-- username field -->
<p>
{{ Form::label('username', 'Username') }}<br/>
{{ Form::text('username', Input::old('username')) }}
</p>
<!-- password field -->
<p>
5
{{ Form::label('password', 'Password') }}<br/>
{{ Form::password('password') }}
</p>
<!-- submit button -->
<p>{{ Form::submit('Login') }}</p>
{{ Form::close() }}
@stop
We use the Form helper class from the Meido Form library. Well explain a few things:
{{ Form::open( , ) }}
Here we specify that the form data should be submitted to the Route::post('login') route.
Rest of the form is fairly self-explanatory. Please refer to the official Meido Form documentation.
Now, lets implement the POST /login route. This route will handle the actual user authentication:
Route::post( , function () {
$user = array(
=> Input::get( ),
=> Input::get( )
);

if (Auth::attempt($user)) {
return Redirect::route( )
->with( , );
}

// authentication failure! lets go back to the login page
return Redirect::route( )
->with( , )
->withInput();
});
First lets get the input data that has been posted from the form:
$user = array(
=> Input::get( ),
=> Input::get( )
);
Logging a user into your application is simple. We will use the Auth::attempt() method to verify the login credentials. The great thing about this
method, is on success it will automatically create our authenticated session for us!
if (Auth::attempt($user)) {
return Redirect::route( )
->with( , );
}
We pass an array containing the username and password of the user to the Auth::attempt() method. If the users credentials are valid, the user ID
will be stored in the session and the user will be considered logged in on subsequent requests to your application. The Auth::attempt() method
will return true if the credentials are valid. Otherwise, false will be returned.
Now if our authentication is successful, the login session is created, and we are redirected to the home route.
Perfect! But before we go any further, lets implement the logout route so that we can logout to perform future testing.
Route::get( , array( => , function () {
Auth::logout();
return Redirect::route( )
->with( , );
}))->before( );
Here we use the Auth::logout() method to destroy the users login session, and head back to the home page. We are now logged out.
Now that we have our login/logout working perfectly lets implement our super-secret private route:
Route::get( , array( => , function () {
return View::make( );
}))->before( );
And below is the content of the corresponding app/views/profile.blade.php template:
@extends('layout')
@section('content')
<h2>Welcome "{{ Auth::user()->username }}" to the protected page!</h2>
<p>Your user ID is: {{ Auth::user()->id }}</p>
@stop
You will notice that we use Auth::user() in the above example. This method will return the currently logged in user object. We can access all the
attributes of our User model using this method.
Here are some screenshots of the demo application we have built.
The first one is the public home page:
6
Now the login form:
Login error page:
Login success page:
7
Prevent duplicate authentication (for logged in users):
The protected profile page:
After logging out:
8
And finally, access denied when you try to visit http://hostname/profile:
Logging In
You may use the Auth::login() method to login a user without checking their credentials, such as after a user first registers to use your
application. Lets see this method in action:
$username = strtolower(Input::get( ));
User::create([
=> $username,
=> Hash::make(Input::get( )),
]);
$user = User::where( , , $username)->first();
Auth::login($user);
In the above snippet we create a new user object, and subsequently log the user into our application.
Prev Table of contents Next
9