Autenticación

Introducción

Laravel hace que la implementación de la autenticación sea muy sencilla. De hecho, todo está configurado para ti sin necesidad de mayores ajustes. El archivo de configuración esta ubicado en config/auth.php, este contiene varias opciones bien documentadas para ajustar el comportamiento de los servicios de autenticación.

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. Si tu aplicación no utiliza Eloquent, puedes utilizar el controlador de autenticación database que utiliza el generador de consultas de Laravel.

When building the database schema for the App\User model, make sure the password column is at least 60 characters in length.

Also, you should verify that your users (or equivalent) table contains a nullable, string remember_token column of 100 characters. Esta columna será utilizada para almacenar el token de las sesiones del tipo "recuérdame" de tu aplicación. Esto puede hacerse usando $table->rememberToken(); en una migración.

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

By default, no routes are included to point requests to the authentication controllers. You may manually add them to your app/Http/routes.php file:

// Authentication routes...
Route::get('auth/login', 'Auth\AuthController@getLogin');
Route::post('auth/login', 'Auth\AuthController@postLogin');
Route::get('auth/logout', 'Auth\AuthController@getLogout');

// Registration routes...
Route::get('auth/register', 'Auth\AuthController@getRegister');
Route::post('auth/register', 'Auth\AuthController@postRegister');

Vistas

Though the authentication controllers are included with the framework, you will need to provide views that these controllers can render. The views should be placed in the resources/views/auth directory. Eres libre de personalizar estas vistas de la forma que prefieras. The login view should be placed at resources/views/auth/login.blade.php, and the registration view should be placed at resources/views/auth/register.blade.php.

Sample Authentication Form

<!-- resources/views/auth/login.blade.php -->

<form method="POST" action="/auth/login">
    {!! csrf_field() !!}

    <div>
        Email
        <input type="email" name="email" value="{{ old('email') }}">
    </div>

    <div>
        Password
        <input type="password" name="password" id="password">
    </div>

    <div>
        <input type="checkbox" name="remember"> Remember Me
    </div>

    <div>
        <button type="submit">Login</button>
    </div>
</form>

Sample Registration Form

<!-- resources/views/auth/register.blade.php -->

<form method="POST" action="/auth/register">
    {!! csrf_field() !!}

    <div class="col-md-6">
        Name
        <input type="text" name="name" value="{{ old('name') }}">
    </div>

    <div>
        Email
        <input type="email" name="email" value="{{ old('email') }}">
    </div>

    <div>
        Password
        <input type="password" name="password">
    </div>

    <div class="col-md-6">
        Confirm Password
        <input type="password" name="password_confirmation">
    </div>

    <div>
        <button type="submit">Register</button>
    </div>
</form>

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 defined routes in a browser. The authentication controllers already contain the logic (via their traits) to authenticate existing users and store new users in the database.

When a user is successfully authenticated, they will be redirected to the /home URI, which you will need to register a route to handle. You can customize the post-authentication redirect location by defining a redirectTo property on the AuthController:

protected $redirectTo = '/dashboard';

Customizations

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. Esta clase es la responsable de validar y crear nuevos usuarios en tu aplicación.

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.

Obtener el usuario autenticado

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:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Routing\Controller;

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.

Protección de las rutas

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');
}

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;
use Illuminate\Routing\Controller;

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');
        }
    }
}

El método attempt acepta un array de pares clave / valor como primer argumento. The values in the array will be used to find the user in your database table. Así, en el ejemplo anterior, el usuario recuperará el valor de la columna de email. Si se encuentra un usuario, la contraseña encriptada almacenada en la base de datos será comparada con el valor encriptado password pasado al método vía array. If the two hashed passwords match an authenticated session will be started for the user.

El método attempt devolverá true si la autenticación tuvo éxito. De lo contrario, devolverá false .

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. Una URI alternativa puede entregarse a este método en caso de que la página a la cual el usuario quería acceder no esté disponible.

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.
}

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();

Note: In these examples, email is not a required option, it is merely used as an example. Puedes utilizar cualquier columna que haga referencia al "nombre de usuario" en tu base de datos.

Remembering Users

Si deseas proporcionar la funcionalidad de "recuérdame" en tu aplicación, puedes pasar true como segundo parámetro al método <0>attempt, el cual mantendrá al usuario autenticado indefinidamente (o hasta que manualmente se desconecte). Por su puesto, tu tabla users debe incluir la columna remember_token del tipo string, la cual será utilizada para almacenar el token de "recuérdame".

if (Auth::attempt(['email' => $email, 'password' => $password], $remember)) {
    // The user is being remembered...
}

Si estás "recordando" usuarios, puedes utilizar el método viaRemember para determinar si un usuario fue autenticado utilizando la cookie de "recuérdame":

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);

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);

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)) {
    //
}

Autenticación HTTP básica

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

Si estás usando PHP FastCGI, la autenticación básica HTTP puede no funcionar adecuadamente de forma directa. Deberás agregar las siguientes líneas a tu archivo .htaccess:

RewriteCond %{HTTP:Authorization} ^(.+)$
RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]

Stateless HTTP Basic Authentication

Puedes también utilizar la autenticación HTTP básica sin establecer un identificador de usuario en la sesión, lo cual es particularmente útil para la autenticación de una API. 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

La mayoría de las aplicaciones web proporcionan la posibilidad de que los usuarios puedan recuperar sus contraseñas olvidadas. En lugar de obligarte a re-implementar esto en cada aplicación, Laravel provee convenientes métodos para enviar recordatorios de contraseña y realizar el reseteo de éstas.

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

A continuación, debes crear una tabla para almacenar los tokens de restablecimiento de contraseña. La migración para esta tabla se incluye con Laravel de serie, y se encuentra en el directorio database/migrations. So, all you need to do is migrate:

php artisan migrate

Rutas

Laravel includes an Auth\PasswordController that contains the logic necessary to reset user passwords. However, you will need to define routes to point requests to this controller:

// Password reset link request routes...
Route::get('password/email', 'Auth\PasswordController@getEmail');
Route::post('password/email', 'Auth\PasswordController@postEmail');

// Password reset routes...
Route::get('password/reset/{token}', 'Auth\PasswordController@getReset');
Route::post('password/reset', 'Auth\PasswordController@postReset');

Vistas

In addition to defining the routes for the PasswordController, you will need to provide views that can be returned by this controller. Don't worry, we will provide sample views to help you get started. Of course, you are free to style your forms however you wish.

Sample Password Reset Link Request Form

You will need to provide an HTML view for the password reset request form. This view should be placed at resources/views/auth/password.blade.php. This form provides a single field for the user's e-mail address, allowing them to request a password reset link:

<!-- resources/views/auth/password.blade.php -->

<form method="POST" action="/password/email">
    {!! csrf_field() !!}

    <div>
        Email
        <input type="email" name="email" value="{{ old('email') }}">
    </div>

    <div>
        <button type="submit">
            Send Password Reset Link
        </button>
    </div>
</form>

When a user submits a request to reset their password, they will receive an e-mail with a link that points to the getReset method (typically routed at /password/reset) of the PasswordController. You will need to create a view for this e-mail at resources/views/emails/password.blade.php. The view will receive the $token variable which contains the password reset token to match the user to the password reset request. Here is an example e-mail view to get you started:

<!-- resources/views/emails/password.blade.php -->

Click here to reset your password: {{ url('password/reset/'.$token) }}

Sample Password Reset Form

When the user clicks the e-mailed link to reset their password, they will be presented with a password reset form. This view should be placed at resources/views/auth/reset.blade.php.

Here is a sample password reset form to get you started:

<!-- resources/views/auth/reset.blade.php -->

<form method="POST" action="/password/reset">
    {!! csrf_field() !!}
    <input type="hidden" name="token" value="{{ $token }}">

    <div>
        <input type="email" name="email" value="{{ old('email') }}">
    </div>

    <div>
        <input type="password" name="password">
    </div>

    <div>
        <input type="password" name="password_confirmation">
    </div>

    <div>
        <button type="submit">
            Reset Password
        </button>
    </div>
</form>

After Resetting Passwords

Once you have defined the routes and views to reset your user's passwords, you may simply access the routes in your browser. 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.

Después de que se restablezca la contraseña, el usuario será automáticamente autenticado en la aplicación y redirigido a /home. You can customize the post password reset redirect location by defining a redirectTo property on the PasswordController:

protected $redirectTo = '/dashboard';

Nota: Por defecto, los tokens de recuperación de contraseña expiran después de una hora. Puedes cambiar esto a través de la opción reminder.expire en tu archivo config/auth.php.

Autenticación social

Además de la forma típica, Laravel también proporciona una manera simple y conveniente para autenticar con proveedores OAuth utilizando Laravel Socialite. Socialite currently supports authentication with Facebook, Twitter, Google, GitHub and Bitbucket.

To get started with Socialite, add to your composer.json file as a dependency:

composer require laravel/socialite

Configuración

After installing the Socialite library, register the Laravel\Socialite\SocialiteServiceProvider in your config/app.php configuration file:

'providers' => [
    // Other service providers...

    Laravel\Socialite\SocialiteServiceProvider::class,
],

Also, add the Socialite facade to the aliases array in your app configuration file:

'Socialite' => Laravel\Socialite\Facades\Socialite::class,

You will also need to add credentials for the OAuth services your application utilizes. Estos credenciales deben ser colocados en el archivo de configuración config/services.php y deben utilizar la clave facebook, twitter, google o github, dependiendo de los proveedores que tu aplicación requiera. Por ejemplo:

'github' => [
    'client_id' => 'su-id-de-github',
    'client_secret' => 'su-secret-de-github',
    'redirect' => 'http://su-url-callback',
],

Uso básico

Ahora, ¡estás listo para autenticar a los usuarios! Necesitarás dos rutas: una para redirigir al usuario al proveedor OAuth y otra para recibir de llamada del proveedor después de la autenticación. We will access Socialite using the Socialite facade:

<?php

namespace App\Http\Controllers;

use Illuminate\Routing\Controller;

class AuthController extends Controller
{
    /**
     * Redirect the user to the GitHub authentication page.
     *
     * @return Response
     */
    public function redirectToProvider()
    {
        return Socialite::driver('github')->redirect();
    }

    /**
     * Obtain the user information from GitHub.
     *
     * @return Response
     */
    public function handleProviderCallback()
    {
        $user = Socialite::driver('github')->user();

        // $user->token;
    }
}

El método redirect se encarga de enviar el usuario con el proveedor de OAuth, mientras que el método de user leerá la solicitud entrante y recuperara la información del usuario desde el proveedor. Before redirecting the user, you may also set "scopes" on the request using the scope method. This method will overwrite all existing scopes:

return Socialite::driver('github')
            ->scopes(['scope1', 'scope2'])->redirect();

Obtener los datos del usuario

Una vez que tengas una instancia de usuario, puedes obtener más detalles de el:

$user = Socialite::driver('github')->user();

// OAuth Two Providers
$token = $user->token;

// OAuth One Providers
$token = $user->token;
$tokenSecret = $user->tokenSecret;

// All Providers
$user->getId();
$user->getNickname();
$user->getName();
$user->getEmail();
$user->getAvatar();

Adding Custom Authentication Drivers

If you are not using a traditional relational database to store your users, you will need to extend Laravel with your own authentication driver. We will use the extend method on the Auth facade to define a custom driver. You should place this call to extend 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::extend('riak', function($app) {
            // 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 driver with the extend method, you may switch to the new driver in your config/auth.php configuration file.

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. Estas dos interfaces permiten al mecanismo de autenticación de Laravel continuar funcionando sin importar como se almacenan los datos del usuario o que tipo de clase es utilizada para representarlos.

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. Se debe obtener la implementación Authenticable que concuerda con el ID y retornarla por el método.

La función retrieveByToken devuelve un usuario dado su identificador único $identifier y $token "recordarme", almacenado en un campo remember_token. Como con el método anterior, debe retornarse una implementación de Authenticatable.

El método updateRememberToken actualiza el campo remember_token para el $user con el nuevo $token. El nuevo token puede ser un token nuevo, asignado en un intento satisfactorio de inicio de sesión "recuérdame", o nulo cuando una sesión de usuario termina.

El método retrieveByCredentials recibe un array con las credenciales que se pasa al método Auth::attempt cuando se intenta iniciar sesión en una aplicación. Entonces el método debe "consultar" a la capa de persistencia subyacente si existe algún usuario que concuerde con esos credenciales. Normalmente, este método ejecuta una consulta con una condición "where" en $credentails['username']. El método debe retornar una implementación de UserInterface. Este método no debe intentar hacer cualquier validación de contraseña o autenticación.

El método validateCredentials debe comparar el $user dado con el $credentials para autenticar al usuario. Por ejemplo, este método podría comparar la cadena $user-> getAuthPassword() con un Hash::make de $credentials ['password']. Este método debe sólo validar los credenciales del usuario y retornar un valor booleano.

The Authenticatable Contract

Ahora que hemos explorado cada uno de los métodos de UserProvider, echemos un vistazo a Authenticatable. Recuerda, el proveedor debe devolver la implementación de esta interfaz desde los métodos retrieveById y retrieveByCredentials:

<?php namespace Illuminate\Contracts\Auth;

interface Authenticatable {

    public function getAuthIdentifier();
    public function getAuthPassword();
    public function getRememberToken();
    public function setRememberToken($value);
    public function getRememberTokenName();

}

Esta interfaz es simple. El método getAuthIdentifier debe devolver el "primary key" del usuario. En un backend MySQL, otra vez, esto sería la clave primaria auto-incremental. El getAuthPassword debe devolver el hash de la contraseña del usuario. Esta interfaz permite que el sistema de autenticación trabaje con cualquier clase de usuario, independientemente de qué capa de abstracción ORM o almacenamiento utiliza. Por defecto, Laravel incluye una clase user en el directorio app que implementa esta interfaz, así que se puede consultar esta clase para obtener un ejemplo de su aplicación.