Introduction
Laravel makes implementing authentication very simple. In
fact, almost everything is configured for you out of the
box. The authentication configuration file is located at
config/auth.php
, which contains several
well documented options for tweaking the behavior of the
authentication services.
At its core, Laravel's authentication facilities are made
up of "guards" and "providers".
Guards define how users are authenticated for each
request. For example, Laravel ships with a
session
guard which maintains state using
session storage and cookies and a token
guard, which authenticates users using a "API
token" that is passed with each request.
Providers define how users are retrieved from your persistent storage. Laravel ships with support for retrieving users using Eloquent and the database query builder. However, you are free to define additional providers as needed for your application.
Don't worry if this all sounds confusing now! Most applications will never need to modify the default authentication configuration.
Database Considerations
By default, Laravel includes an App\User
Eloquent model in your
app
directory. This model may be used with
the default Eloquent authentication driver. If your
application is not using Eloquent, you may use the
database
authentication driver which uses
the Laravel query builder.
When building the database schema for the
App\User
model, make sure the password
column is at least 60 characters in length, the default
of 255 would be a good choice.
Also, you should verify that your users
(or
equivalent) table contains a nullable, string
remember_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.
Authentication Quickstart
Laravel ships with two authentication controllers out of
the box, which are located in the
App\Http\Controllers\Auth
namespace. The
AuthController
handles new user
registration and authentication, while the
PasswordController
contains the logic to
help existing users reset their forgotten passwords.
Each of these controllers uses a trait to include their
necessary methods. For many applications, you will not
need to modify these controllers at all.
Routing
Laravel provides a quick way to scaffold all of the routes and views you need for authentication using one simple command:
php artisan make:auth
This command should be used on fresh applications and
will install registration and login views, as well as
routes for all authentication end-points. A
HomeController
will also be generated,
which serves post-login requests to your application's
dashboard. However, you are free to customize or even
remove this controller based on the needs of your
application.
Views
As mentioned in the previous section, the php
artisan make:auth
command will create all of
the views you need for authentication and place them in
the resources/views/auth
directory.
The make:auth
command will also create a
resources/views/layouts
directory
containing a base layout for your application. All of
these views use the Bootstrap CSS framework, but you are
free to customize them however you wish.
Authenticating
Now that you have routes and views setup for the included authentication controllers, you are ready to register and authenticate new users for your application! You may simply access your application in a browser. The authentication controllers already contain the logic (via their traits) to authenticate existing users and store new users in the database.
Path Customization
When a user is successfully authenticated, they will be
redirected to the /
URI. You can customize
the post-authentication redirect location by defining a
redirectTo
property on the
AuthController
:
protected $redirectTo = '/home';
When a user is not successfully authenticated, they will be redirected back to the login form location automatically.
Guard Customization
You may also customize the "guard" that is used
to authenticate users. To get started, define a
guard
property on your
AuthController
. The value of this property
should correspond with one of the guards configured in
your auth.php
configuration file:
protected $guard = 'admin';
Validation / Storage Customization
To modify the form fields that are required when a new
user registers with your application, or to customize
how new user records are inserted into your database,
you may modify the AuthController
class.
This class is responsible for validating and creating
new users of your application.
The validator
method of the
AuthController
contains the validation
rules for new users of the application. You are free to
modify this method as you wish.
The create
method of the
AuthController
is responsible for creating
new App\User
records in your database using
the Eloquent ORM. You are
free to modify this method according to the needs of
your database.
Retrieving The Authenticated User
You may access the authenticated user via the
Auth
facade:
$user = Auth::user();
Alternatively, once a user is authenticated, you may
access the authenticated user via an
Illuminate\Http\Request
instance. Remember,
type-hinted classes will automatically be injected into
your controller methods:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class ProfileController extends Controller
{
/**
* Update the user's profile.
*
* @param Request $request
* @return Response
*/
public function updateProfile(Request $request)
{
if ($request->user()) {
// $request->user() returns an instance of the authenticated user...
}
}
}
Determining If The Current User Is Authenticated
To determine if the user is already logged into your
application, you may use the check
method
on the Auth
facade, which will return
true
if the user is authenticated:
if (Auth::check()) {
// The user is logged in...
}
However, you may use middleware to verify that the user is authenticated before allowing the user access to certain routes / controllers. To learn more about this, check out the documentation on protecting routes.
Protecting Routes
Route middleware can be
used to allow only authenticated users to access a given
route. Laravel ships with the auth
middleware, which is defined in
app\Http\Middleware\Authenticate.php
. All
you need to do is attach the middleware to a route
definition:
// Using A Route Closure...
Route::get('profile', ['middleware' => 'auth', function() {
// Only authenticated users may enter...
}]);
// Using A Controller...
Route::get('profile', [
'middleware' => 'auth',
'uses' => 'ProfileController@show'
]);
Of course, if you are using controller classes, you
may call the middleware
method from the
controller's constructor instead of attaching it in the
route definition directly:
public function __construct()
{
$this->middleware('auth');
}
Specifying A Guard
When attaching the auth
middleware to a
route, you may also specify which guard should be used
to perform the authentication:
Route::get('profile', [
'middleware' => 'auth:api',
'uses' => 'ProfileController@show'
]);
The guard specified should correspond to one of the keys
in the guards
array of your
auth.php
configuration file.
Authentication Throttling
If you are using Laravel's built-in
AuthController
class, the
Illuminate\Foundation\Auth\ThrottlesLogins
trait may be used to throttle login attempts to your
application. By default, the user will not be able to
login for one minute if they fail to provide the correct
credentials after several attempts. The throttling is
unique to the user's username / e-mail address and their
IP address:
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use Validator;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Illuminate\Foundation\Auth\AuthenticatesAndRegistersUsers;
class AuthController extends Controller
{
use AuthenticatesAndRegistersUsers, ThrottlesLogins;
// Rest of AuthController class...
}
Manually Authenticating Users
Of course, you are not required to use the authentication controllers included with Laravel. If you choose to remove these controllers, you will need to manage user authentication using the Laravel authentication classes directly. Don't worry, it's a cinch!
We will access Laravel's authentication services via the
Auth
facade, so
we'll need to make sure to import the Auth
facade at the top of the class. Next, let's check out
the attempt
method:
<?php
namespace App\Http\Controllers;
use Auth;
class AuthController extends Controller
{
/**
* Handle an authentication attempt.
*
* @return Response
*/
public function authenticate()
{
if (Auth::attempt(['email' => $email, 'password' => $password])) {
// Authentication passed...
return redirect()->intended('dashboard');
}
}
}
The attempt
method accepts an array of key /
value pairs as its first argument. The values in the
array will be used to find the user in your database
table. So, in the example above, the user will be
retrieved by the value of the email
column.
If the user is found, the hashed password stored in the
database will be compared with the hashed
password
value passed to the method via the
array. If the two hashed passwords match an
authenticated session will be started for the user.
The attempt
method will return
true
if authentication was successful.
Otherwise, false
will be returned.
The intended
method on the redirector will
redirect the user to the URL they were attempting 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.
Specifying Additional Conditions
If you wish, you also may add extra conditions to the authentication query in addition to the user's e-mail and password. For example, we may verify that user is marked as "active":
if (Auth::attempt(['email' => $email, 'password' => $password, 'active' => 1])) {
// The user is active, not suspended, and exists.
}
Note: In these examples,
Accessing Specific Guard Instances
You may specify which guard instance you would like to
utilize using the guard
method on the
Auth
facade. This allows you to manage
authentication for separate parts of your application
using entirely separate authenticatable models or user
tables.
The guard name passed to the guard
method
should correspond to one of the guards configured in
your auth.php
configuration file:
if (Auth::guard('admin')->attempt($credentials)) {
//
}
Logging Out
To log users out of your application, you may use the
logout
method on the Auth
facade. This will clear the authentication information
in the user's session:
Auth::logout();
Remembering Users
If you would like to provide "remember me"
functionality in your application, you may pass a
boolean value 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(['email' => $email, 'password' => $password], $remember)) {
// The user is being remembered...
}
If you are "remembering" users, you may use the
viaRemember
method to determine if the user
was authenticated using the "remember me"
cookie:
if (Auth::viaRemember()) {
//
}
Other Authentication Methods
Authenticate A User Instance
If you need to log an existing user instance into your
application, you may call the login
method
with the user instance. The given object must be an
implementation of the
Illuminate\Contracts\Auth\Authenticatable
contract. Of course, the
App\User
model included with Laravel
already implements this interface:
Auth::login($user);
// Login and "remember" the given user...
Auth::login($user, true);
Of course, you may specify the guard instance you would like to use:
Auth::guard('admin')->login($user);
Authenticate A User By ID
To log a user into the application by their ID, you may
use the loginUsingId
method. This method
simply accepts the primary key of the user you wish to
authenticate:
Auth::loginUsingId(1);
// Login and "remember" the given user...
Auth::loginUsingId(1, true);
Authenticate A User Once
You may use the once
method to log a user
into the application for a single request. No sessions
or cookies will be utilized, which may be helpful when
building a stateless API. The once
method
has the same signature as the attempt
method:
if (Auth::once($credentials)) {
//
}
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
middleware to your route.
The auth.basic
middleware is included with
the Laravel framework, so you do not need to define
it:
Route::get('profile', ['middleware' => 'auth.basic', function() {
// Only authenticated users may enter...
}]);
Once the middleware has been attached to the route, you
will automatically be prompted for credentials when
accessing the route in your browser. By default, the
auth.basic
middleware will use the
email
column on the user record as the
"username".
A Note On FastCGI
If you are using PHP FastCGI, HTTP Basic authentication
may not work correctly out of the box. The following
lines should be added to your .htaccess
file:
RewriteCond %{HTTP:Authorization} ^(. )$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
Stateless HTTP Basic Authentication
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 middleware that
calls the onceBasic
method. If no response
is returned by the onceBasic
method, the
request may be passed further into the application:
<?php
namespace Illuminate\Auth\Middleware;
use Auth;
use Closure;
class AuthenticateOnceWithBasicAuth
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
return Auth::onceBasic() ?: $next($request);
}
}
Next, register the route middleware and attach it to a route:
Route::get('api/user', ['middleware' => 'auth.basic.once', function() {
// Only authenticated users may enter...
}]);
Resetting Passwords
Database Considerations
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 App\User
model implements the
Illuminate\Contracts\Auth\CanResetPassword
contract. Of course, the App\User
model
included with the framework already implements this
interface, and uses the
Illuminate\Auth\Passwords\CanResetPassword
trait to include the methods needed to implement the
interface.
Generating The Reset Token Table Migration
Next, a table must be created to store the password reset
tokens. The migration for this table is included with
Laravel out of the box, and resides in the
database/migrations
directory. So, all you
need to do is migrate:
php artisan migrate
Routing
Laravel includes an Auth\PasswordController
that contains the logic necessary to reset user
passwords. All of the routes needed to perform password
resets may be generated using the make:auth
Artisan command:
php artisan make:auth
Views
Again, Laravel will generate all of the necessary views
for password reset when the make:auth
command is executed. These views are placed in
resources/views/auth/passwords
. You are
free to customize them as needed for your
application.
After Resetting Passwords
Once you have defined the routes and views to reset your
user's passwords, you may simply access the route in
your browser at /password/reset
. The
PasswordController
included with the
framework already includes the logic to send the
password reset link e-mails as well as update passwords
in the database.
After the password is reset, the user will automatically
be logged into the application and redirected to
/home
. You can customize the post password
reset redirect location by defining a
redirectTo
property on the
PasswordController
:
protected $redirectTo = '/dashboard';
Note: By default, password reset tokens expire after one hour. You may change this via the password reset
expire
option in yourconfig/auth.php
file.
Customization
Authentication Guard Customization
In your auth.php
configuration file, you may
configure multiple "guards", which may be used
to define authentication behavior for multiple user
tables. You can customize the included
PasswordController
to use the guard of your
choice by adding a $guard
property to the
controller:
/**
* The authentication guard that should be used.
*
* @var string
*/
protected $guard = 'admins';
Password Broker Customization
In your auth.php
configuration file, you may
configure multiple password "brokers", which
may be used to reset passwords on multiple user tables.
You can customize the included
PasswordController
to use the broker of
your choice by adding a $broker
property to
the controller:
/**
* The password broker that should be used.
*
* @var string
*/
protected $broker = 'admins';
Adding Custom Guards
You may define your own authentication guards using the
extend
method on the Auth
facade. You should place this call to
provider
within a service provider:
<?php
namespace App\Providers;
use Auth;
use App\Services\Auth\JwtGuard;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Auth::extend('jwt', function($app, $name, array $config) {
// Return an instance of Illuminate\Contracts\Auth\Guard...
return new JwtGuard(Auth::createUserProvider($config['provider']));
});
}
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
}
As you can see in the example above, the callback passed
to the extend
method should return an
implementation of
Illuminate\Contracts\Auth\Guard
. This
interface contains a few methods you will need to
implement to define a custom guard.
Once your custom guard has been defined, you may use the
guard in your guards
configuration:
'guards' => [
'api' => [
'driver' => 'jwt',
'provider' => 'users',
],
],
Adding Custom User Providers
If you are not using a traditional relational database to
store your users, you will need to extend Laravel with
your own authentication user provider. We will use the
provider
method on the Auth
facade to define a custom user provider. You should
place this call to provider
within a service provider:
<?php
namespace App\Providers;
use Auth;
use App\Extensions\RiakUserProvider;
use Illuminate\Support\ServiceProvider;
class AuthServiceProvider extends ServiceProvider
{
/**
* Perform post-registration booting of services.
*
* @return void
*/
public function boot()
{
Auth::provider('riak', function($app, array $config) {
// Return an instance of Illuminate\Contracts\Auth\UserProvider...
return new RiakUserProvider($app['riak.connection']);
});
}
/**
* Register bindings in the container.
*
* @return void
*/
public function register()
{
//
}
}
After you have registered the provider with the
provider
method, you may switch to the new
user provider in your config/auth.php
configuration file. First, define a
provider
that uses your new driver:
'providers' => [
'users' => [
'driver' => 'riak',
],
],
Then, you may use this provider in your
guards
configuration:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
],
The User Provider Contract
The Illuminate\Contracts\Auth\UserProvider
implementations are only responsible for fetching a
Illuminate\Contracts\Auth\Authenticatable
implementation out of a persistent storage system, such
as MySQL, Riak, etc. These two interfaces allow the
Laravel authentication mechanisms to continue
functioning regardless of how the user data is stored or
what type of class is used to represent it.
Let's take a look at the
Illuminate\Contracts\Auth\UserProvider
contract:
<?php
namespace Illuminate\Contracts\Auth;
interface UserProvider {
public function retrieveById($identifier);
public function retrieveByToken($identifier, $token);
public function updateRememberToken(Authenticatable $user, $token);
public function retrieveByCredentials(array $credentials);
public function validateCredentials(Authenticatable $user, array $credentials);
}
The retrieveById
function typically receives
a key representing the user, such as an
auto-incrementing ID from a MySQL database. The
Authenticatable
implementation matching the
ID should be retrieved and returned by the method.
The retrieveByToken
function retrieves a
user by their unique $identifier
and
"remember me" $token
, stored in a
field remember_token
. As with the previous
method, the Authenticatable
implementation
should be returned.
The updateRememberToken
method updates the
$user
field remember_token
with the new $token
. The new token can be
either a fresh token, assigned on a successful
"remember me" login attempt, or a null when
the user is logged out.
The retrieveByCredentials
method receives
the array of credentials passed to the
Auth::attempt
method when attempting to
sign into an application. The method should then
"query" the underlying persistent storage for
the user matching those credentials. Typically, this
method will run a query with a "where"
condition on $credentials['username']
. The
method should then return an implementation of
UserInterface
. This method should
not attempt to do any password validation or
authentication.
The validateCredentials
method should
compare the given $user
with the
$credentials
to authenticate the user. For
example, this method might compare the
$user->getAuthPassword()
string to a
Hash::make
of
$credentials['password']
. This method
should only validate the user's credentials and return a
boolean.
The Authenticatable Contract
Now that we have explored each of the methods on the
UserProvider
, let's take a look at the
Authenticatable
contract. Remember, the
provider should return implementations of this interface
from the retrieveById
and
retrieveByCredentials
methods:
<?php
namespace Illuminate\Contracts\Auth;
interface Authenticatable {
public function getAuthIdentifierName();
public function getAuthIdentifier();
public function getAuthPassword();
public function getRememberToken();
public function setRememberToken($value);
public function getRememberTokenName();
}
This interface is simple. The
getAuthIdentifierName
method should return
the name of the "primary key" field of the
user and the getAuthIdentifier
method
should return the "primary key" of the user.
In a MySQL back-end, again, this would be the
auto-incrementing primary key. The
getAuthPassword
should return the user's
hashed password. This interface allows the
authentication system to work with any User class,
regardless of what ORM or storage abstraction layer you
are using. By default, Laravel includes a
User
class in the app
directory which implements this interface, so you may
consult this class for an implementation example.
Events
Laravel raises a variety of events during the
authentication process. You may attach listeners to
these events in your
EventServiceProvider
:
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Illuminate\Auth\Events\Attempting' => [
'App\Listeners\LogAuthenticationAttempt',
],
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogSuccessfulLogin',
],
'Illuminate\Auth\Events\Logout' => [
'App\Listeners\LogSuccessfulLogout',
],
'Illuminate\Auth\Events\Lockout' => [
'App\Listeners\LogLockout',
],
];