Configuration
Laravel aims to make implementing authentication very simple. In
fact, almost everything is configured for you out of the box. The
authentication configuration file is located at
app/config/auth.php
, which contains several well documented
options for tweaking the behavior of the authentication facilities.
By default, Laravel includes a User
model in your
app/models
directory which may be used with the default
Eloquent authentication driver. Please remember when building the Schema
for this Model to ensure that the password field is a minimum of 60
characters.
If your application is not using Eloquent, you may use the
database
authentication driver which uses the Laravel query
builder.
Note: Before getting started, make sure that your
users
(or equivalent) table contains a nullable, stringremember_token
column of 100 characters. This column will be used to store a token for "remember me" sessions being maintained by your application. This can be done by using$table->rememberToken();
in a migration.
Storing Passwords
The Laravel Hash
class provides secure Bcrypt
hashing:
Hashing A Password Using Bcrypt
$password = Hash::make('secret');
Verifying A Password Against A Hash
if (Hash::check('secret', $hashedPassword))
{
// The passwords match...
}
Checking If A Password Needs To Be Rehashed
if (Hash::needsRehash($hashed))
{
$hashed = Hash::make('secret');
}
Authenticating Users
To log a user into your application, you may use the
Auth::attempt
method.
if (Auth::attempt(array('email' => $email, 'password' => $password)))
{
return Redirect::intended('dashboard');
}
Take note that email
is not a required option, it is
merely used for example. You should use whatever column name corresponds
to a "username" in your database. The Redirect::intended
function will redirect the user to the URL they were trying to access
before being caught by the authentication filter. A fallback URI may be
given to this method in case the intended destination is not
available.
When the attempt
method is called, the
auth.attempt
event will be fired.
If the authentication attempt is successful and the user is logged in,
the auth.login
event will be fired as well.
Determining If A User Is Authenticated
To determine if the user is already logged into your application, you
may use the check
method:
if (Auth::check())
{
// The user is logged in...
}
Authenticating A User And "Remembering" Them
If you would like to provide "remember me" functionality in your
application, you may pass true
as the second argument to
the attempt
method, which will keep the user authenticated
indefinitely (or until they manually logout). Of course, your
users
table must include the string
remember_token
column, which will be used to store the
"remember me" token.
if (Auth::attempt(array('email' => $email, 'password' => $password), true))
{
// The user is being remembered...
}
Note: If the attempt
method returns
true
, the user is considered logged into the
application.
Determining If User Authed Via Remember
If you are "remembering" user logins, you may use the
viaRemember
method to determine if the user was
authenticated using the "remember me" cookie:
if (Auth::viaRemember())
{
//
}
Authenticating A User With Conditions
You also may add extra conditions to the authenticating query:
if (Auth::attempt(array('email' => $email, 'password' => $password, 'active' => 1)))
{
// The user is active, not suspended, and exists.
}
Note: For added protection against session fixation, the user's session ID will automatically be regenerated after authenticating.
Accessing The Logged In User
Once a user is authenticated, you may access the User model / record:
$email = Auth::user()->email;
To retrieve the authenticated user's ID, you may use the
id
method:
$id = Auth::id();
To simply log a user into the application by their ID, use the
loginUsingId
method:
Auth::loginUsingId(1);
Validating User Credentials Without Login
The validate
method allows you to validate a user's
credentials without actually logging them into the application:
if (Auth::validate($credentials))
{
//
}
Logging A User In For A Single Request
You may also use the once
method to log a user into the
application for a single request. No sessions or cookies will be
utilized.
if (Auth::once($credentials))
{
//
}
Logging A User Out Of The Application
Auth::logout();
Manually Logging In Users
If you need to log an existing user instance into your application,
you may simply call the login
method with the instance:
$user = User::find(1);
Auth::login($user);
This is equivalent to logging in a user via credentials using the
attempt
method.
Protecting Routes
Route filters may be used to allow only authenticated users to access
a given route. Laravel provides the auth
filter by default,
and it is defined in app/filters.php
.
Protecting A Route
Route::get('profile', array('before' => 'auth', function()
{
// Only authenticated users may enter...
}));
CSRF Protection
Laravel provides an easy method of protecting your application from cross-site request forgeries.
Inserting CSRF Token Into Form
<input type="hidden" name="_token" value="<?php echo csrf_token(); ?>">
Validate The Submitted CSRF Token
Route::post('register', array('before' => 'csrf', function()
{
return 'You gave a valid CSRF token!';
}));
HTTP Basic Authentication
HTTP Basic Authentication provides a quick way to authenticate users
of your application without setting up a dedicated "login" page. To get
started, attach the auth.basic
filter to your route:
Protecting A Route With HTTP Basic
Route::get('profile', array('before' => 'auth.basic', function()
{
// Only authenticated users may enter...
}));
By default, the basic
filter will use the
email
column on the user record when authenticating. If you
wish to use another column you may pass the column name as the first
parameter to the basic
method in your
app/filters.php
file:
Route::filter('auth.basic', function()
{
return Auth::basic('username');
});
Setting Up A Stateless HTTP Basic Filter
You may also use HTTP Basic Authentication without setting a user
identifier cookie in the session, which is particularly useful for API
authentication. To do so, define a filter that returns the
onceBasic
method:
Route::filter('basic.once', function()
{
return Auth::onceBasic();
});
If you are using PHP FastCGI, HTTP Basic authentication will not work
correctly by default. The following lines should be added to your
.htaccess
file:
RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Password Reminders & Reset
Model & Table
Most web applications provide a way for users to reset their
forgotten passwords. Rather than forcing you to re-implement this on
each application, Laravel provides convenient methods for sending
password reminders and performing password resets. To get started,
verify that your User
model implements the
Illuminate\Auth\Reminders\RemindableInterface
contract. Of
course, the User
model included with the framework already
implements this interface, and uses the
Illuminate\Auth\Reminders\RemindableTrait
to include the
methods needed to implement the interface.
Implementing The RemindableInterface
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements RemindableInterface {
use RemindableTrait;
}
Generating The Reminder Table Migration
Next, a table must be created to store the password reset tokens. To
generate a migration for this table, simply execute the
auth:reminders-table
Artisan command:
php artisan auth:reminders-table
php artisan migrate
Password Reminder Controller
Now we're ready to generate the password reminder controller. To
automatically generate a controller, you may use the
auth:reminders-controller
Artisan command, which will
create a RemindersController.php
file in your
app/controllers
directory.
php artisan auth:reminders-controller
The generated controller will already have a getRemind
method that handles showing your password reminder form. All you need to
do is create a password.remind
view. This view should have a basic form
with an email
field. The form should POST to the
RemindersController@postRemind
action.
A simple form on the password.remind
view might look
like this:
<form action="{{ action('RemindersController@postRemind') }}" method="POST">
<input type="email" name="email">
<input type="submit" value="Send Reminder">
</form>
In addition to getRemind
, the generated controller will
already have a postRemind
method that handles sending the
password reminder e-mails to your users. This method expects the
email
field to be present in the POST
variables. If the reminder e-mail is successfully sent to the user, a
status
message will be flashed to the session. If the
reminder fails, an error
message will be flashed
instead.
Within the postRemind
controller method you may modify
the message instance before it is sent to the user:
Password::remind(Input::only('email'), function($message)
{
$message->subject('Password Reminder');
});
Your user will receive an e-mail with a link that points to the
getReset
method of the controller. The password reminder
token, which is used to identify a given password reminder attempt, will
also be passed to the controller method. The action is already
configured to return a password.reset
view which you should
build. The token
will be passed to the view, and you should
place this token in a hidden form field named token
. In
addition to the token
, your password reset form should
contain email
, password
, and
password_confirmation
fields. The form should POST to the
RemindersController@postReset
method.
A simple form on the password.reset
view might look like
this:
<form action="{{ action('RemindersController@postReset') }}" method="POST">
<input type="hidden" name="token" value="{{ $token }}">
<input type="email" name="email">
<input type="password" name="password">
<input type="password" name="password_confirmation">
<input type="submit" value="Reset Password">
</form>
Finally, the postReset
method is responsible for
actually changing the password in storage. In this controller action,
the Closure passed to the Password::reset
method sets the
password
attribute on the User
and calls the
save
method. Of course, this Closure is assuming your
User
model is an Eloquent
model; however, you are free to change this Closure as needed to be
compatible with your application's database storage system.
If the password is successfully reset, the user will be redirected to
the root of your application. Again, you are free to change this
redirect URL. If the password reset fails, the user will be redirect
back to the reset form, and an error
message will be
flashed to the session.
Password Validation
By default, the Password::reset
method will verify that
the passwords match and are >= six characters. You may customize
these rules using the Password::validator
method, which
accepts a Closure. Within this Closure, you may do any password
validation you wish. Note that you are not required to verify that the
passwords match, as this will be done automatically by the
framework.
Password::validator(function($credentials)
{
return strlen($credentials['password']) >= 6;
});
Note: By default, password reset tokens expire after one hour. You may change this via the
reminder.expire
option of yourapp/config/auth.php
file.
Encryption
Laravel provides facilities for strong AES encryption via the mcrypt PHP extension:
Encrypting A Value
$encrypted = Crypt::encrypt('secret');
Note: Be sure to set a 16, 24, or 32 character random string in the
key
option of theapp/config/app.php
file. Otherwise, encrypted values will not be secure.
Decrypting A Value
$decrypted = Crypt::decrypt($encryptedValue);
Setting The Cipher & Mode
You may also set the cipher and mode used by the encrypter:
Crypt::setMode('ctr');
Crypt::setCipher($cipher);
Authentication Drivers
Laravel offers the database
and eloquent
authentication drivers out of the box. For more information about adding
additional authentication drivers, check out the Authentication extension
documentation.