Cómo implementar la verificación de contraseñas mediante la solicitud de formulario de Laravel

Introducción

Índice
  1. Introducción
  • Prerrequisitos
  • Paso 1: creación de la vista
  • Paso 2: Creación de la solicitud de formulario
  • Paso 3: Configuración del controlador
  • Paso 4: Configuración de rutas protegidas y mutadores de datos
  • Conclusión
  • Las solicitudes de formulario de Laravel son clases especiales que amplían la funcionalidad de las clases de solicitud normales, lo que permite funciones de validación avanzadas. Las solicitudes de formulario también ayudan a mantener las acciones de tu controlador mucho más limpias, porque puedes mover toda tu lógica de validación a la clase de solicitud de formulario. Otro beneficio es que te permite filtrar las solicitudes antes de que lleguen a las acciones de tu controlador.

    En esta guía, implementaremos un paso de verificación de contraseña para solicitar que un usuario confirme su contraseña antes de acceder a un área de administración. Esta práctica funciona como una doble verificación y le brinda a su aplicación una capa adicional de seguridad.

    Prerrequisitos

    Para continuar con esta guía, necesitará una aplicación Laravel 5.6+ que funcione y que tenga configurada la autenticación de Laravel integrada. Consulte la documentación oficial para obtener detalles sobre cómo configurarla.

    Paso 1: creación de la vista

    Comenzaremos configurando la página de edición del perfil de un usuario.

    Al momento de escribir este tutorial, artisanla utilidad de comando no genera vistas, por lo que necesitaremos crear la vista manualmente.

    Crea el archivo resources/views/profile/edit.blade.phpy agrega el siguiente código.

    @extends('layouts.app')@section('content')div    @if (session('info'))        div            div                div                    button type="button" data-dismiss="alert" aria-hidden="true"×/button                    {{ session('info') }}                /div            /div        /div            @elseif (session('error'))        div            div                div                    button type="button" data-dismiss="alert" aria-hidden="true"×/button                    {{ session('error') }}                /div            /div        /div    @endif    div        div            div                divUpdate Profile/div                div                    form method="POST" action="{{ route('profile.update', ['user' = $user]) }}"                        {{ csrf_field() }}                        {{ method_field('PUT') }}                        div                            label for="name"Name/label                            div                                input type="text" name="name" value="{{ $user-name }}"                                @if ($errors-has('name'))                                    span                                        strong{{ $errors-first('name') }}/strong                                    /span                                @endif                            /div                        /div                        div                            label for="password"Password/label                            div                                input type="password" name="password"                                @if ($errors-has('password'))                                    span                                        strong{{ $errors-first('password') }}/strong                                    /span                                @endif                            /div                        /div                        div                            label for="password-confirm"Confirm Password/label                            div                                input type="password" name="password_confirmation"                            /div                        /div                        div                            label for="current-password"Current Password/label                            div                                input type="password" name="current_password"                                @if ($errors-has('current_password'))                                    span                                        strong{{ $errors-first('current_password') }}/strong                                    /span                                @endif                            /div                        /div                        div                            div                                button type="submit"                                    Update                                /button                            /div                        /div                    /form                /div            /div        /div    /div/div@endsection

    En nuestra página de “editar perfil”, buscamos un infomensaje errorflash y se lo mostramos al usuario.

    Tiene un campo name, password, password_confirmationy current_password.

    La forma en que queremos que funcione es que cada vez que un usuario realiza un cambio, debe proporcionar el current_passwordcampo correcto para confirmar la actualización en la base de datos.

    Los campos passwordy password_confirmationpermiten al usuario cambiar su contraseña. Si ambos campos se dejan vacíos, se conservará la contraseña actual del usuario y no se realizarán cambios en la contraseña almacenada.

    En nuestra opinión, los actores principales son los campos password, password_confirmation, y current_password.

    En cuanto al namecampo, sirve como ejemplo para ampliar y agregar más campos para su caso.

    Paso 2: Creación de la solicitud de formulario

    Ahora pasemos a la parte más crucial de este tutorial.

    Ejecute el siguiente comando para crear una solicitud de formulario.

    1. php artisan make:request UpdateProfile

    El comando anterior creará un archivo llamado app/Http/Requests/UpdateProfile.php.

    Todos los cambios de código en esta sección se realizarán en este archivo.

    Lo primero que debemos hacer es crear un alias para la fachada Hash de Laravel antes de la declaración de la clase.

    use IlluminateSupportFacadesHash;

    A continuación, debemos regresar truede nuestro authorizemétodo ya que no estamos realizando autorización en nuestra solicitud de formulario.

    /** * Determine if the user is authorized to make this request. * * @return bool */public function authorize(){    return true;}

    Nuestro método de reglas devolverá la matriz que describe las reglas de validación para esta solicitud.

    /** * Get the validation rules that apply to the request. * * @return array */public function rules(){    return [        'name' = 'required|string|max:255',        'password' = 'nullable|required_with:password_confirmation|string|confirmed',        'current_password' = 'required',    ];}

    Las namereglas current_passwordse explican por sí solas.

    Las passwordreglas establecen que la contraseña se confirmará mediante la confirmeddeclaración.

    También declara required_with:password_confirmationlo que significa que si el usuario proporciona una confirmación de contraseña, también debe proporcionar una contraseña.

    Estas reglas de validación se comprobarán automáticamente en cada solicitud una vez que las escribamos en nuestra acción del controlador (lo que haremos más adelante).

    Lo último que debemos hacer es declarar un withValidatormétodo en nuestra solicitud al que se le pasa la instancia del validador completamente construida antes de que se active cualquiera de las reglas de validación.

    /** * Configure the validator instance. * * @param  IlluminateValidationValidator  $validator * @return void */public function withValidator($validator){    // checks user current password    // before making changes    $validator-after(function ($validator) {        if ( !Hash::check($this-current_password, $this-user()-password) ) {            $validator-errors()-add('current_password', 'Your current password is incorrect.');        }    });    return; }

    Dentro de nuestro withValdatormétodo, hemos agregado un aftergancho, una función que se ejecutará después de que se hayan realizado todas las comprobaciones de validación.

    En nuestro aftergancho, hemos comparado la contraseña proporcionada por el usuario con su contraseña establecida en la base de datos.

    Nos da $this-current_passwordel current_passwordvalor del campo de formulario, mientras que Laravel nos permite acceder al usuario actualmente autenticado mediante, $this-user()por lo que $this-user()-passwordnos da la contraseña en hash del usuario guardada en la base de datos.

    Las dos contraseñas se comparan utilizando el método Hashde la fachada check.

    Si la comprobación del hash falla, se agrega un error al validador con la clave current_passwordque usa $validator-errors()-add('current_password', 'Your current password is incorrect.').

    Aquí está nuestro UpdateProfileformulario de solicitud completo.

    ?phpnamespace AppHttpRequests;use IlluminateFoundationHttpFormRequest;use IlluminateSupportFacadesHash;class UpdateProfile extends FormRequest{    /**     * Determine if the user is authorized to make this request.     *     * @return bool     */    public function authorize()    {        return true;    }    /**     * Get the validation rules that apply to the request.     *     * @return array     */    public function rules()    {        return [            'name' = 'required|string|max:255',            'password' = 'nullable|required_with:password_confirmation|string|confirmed',            'current_password' = 'required',        ];    }    /**     * Configure the validator instance.     *     * @param  IlluminateValidationValidator  $validator     * @return void     */    public function withValidator($validator)    {        // checks user current password        // before making changes        $validator-after(function ($validator) {            if ( !Hash::check($this-current_password, $this-user()-password) ) {                $validator-errors()-add('current_password', 'Your current password is incorrect.');            }        });        return;    }}

    Paso 3: Configuración del controlador

    Para utilizar nuestra solicitud de formulario, necesitaremos escribirla en nuestra acción de controlador.

    Ejecute el siguiente comando para generar el controlador de perfil.

    1. php artisan make:controller ProfileController

    Abra el archivo app/Http/Controllers/ProfileController.phpy agregue las siguientes acciones del controlador.

    public function __construct(){    $this-middleware('auth');}/** * Show the form for editing the specified resource. * * @param  AppUser  $user * @return IlluminateHttpResponse */public function edit(Request $request, User $user){    // user    $viewData = [        'user' = $user,    ];    // render view with data    return view('profile.edit', $viewData);}/** * Update the specified resource in storage. * * @param  IlluminateHttpRequest  $request * @param  AppUser  $user * @return IlluminateHttpResponse */public function update(UpdateProfile $request, User $user){    // form data    $data = $request-all();    $user-update($data);    return redirect(route('profile.edit', ['user' = $user]))                -with('info', 'Your profile has been updated successfully.');}

    El constructor del controlador de perfil configura el authmiddleware para asegurarse de que un usuario haya iniciado sesión antes de editar su perfil.

    La editacción sirve a la vista con los datos de la vista mientras que la updateacción actualiza el perfil del usuario y redirecciona nuevamente a la página de edición del perfil con el mensaje flash correspondiente.

    Tenga en cuenta la firma de la editacción donde hemos indicado el tipo de UpdateProfilesolicitud, que es todo lo que necesitamos hacer para activar las validaciones dentro de nuestra UpdateProfilesolicitud de formulario.

    También necesitará crear un alias para la solicitud de formulario y el modelo de usuario antes de la declaración de la clase del controlador.

    use AppHttpRequestsUpdateProfile;use AppUser;

    Paso 4: Configuración de rutas protegidas y mutadores de datos

    Abra el archivo app/routes/web.phpy agregue el siguiente código para vincular las acciones del controlador.

    Route::get('/profile/{user}/edit', 'ProfileController@edit')-name('profile.edit');Route::put('/profile/{user}', 'ProfileController@update')-name('profile.update');

    Según la regla de validación que agregamos anteriormente a nuestra solicitud de formulario, es posible que nullpase una contraseña.

    Bajo ninguna circunstancia un usuario (o un desarrollador de aplicaciones) querría que su contraseña sea nulluna cadena vacía.

    Para asegurarnos de que la contraseña de un usuario se configure solo cuando éste la proporcione, utilizaremos los mutadores de Eloquent ORM.

    Abra el archivo app/User.phpy agregue el siguiente código.

    // Only accept a valid password and // hash a password before savingpublic function setPasswordAttribute($password){    if ( $password !== null  $password !== "" )    {        $this-attributes['password'] = bcrypt($password);    }}

    Los mutadores elocuentes deben seguir el esquema de nombres setcamel-cased-attribute-nameAttribute.

    Dado que estamos declarando un mutador para el passwordatributo, hemos llamado al mutador setPasswordAttribute.

    A la función mutadora se le pasa el valor que se está estableciendo, que en nuestro mutador es la $passwordvariable.

    En nuestro mutador, verificamos si la $passwordvariable no es nula o una cadena vacía y la establecemos en nuestro modelo usando $this-attributes['password'].

    Tenga en cuenta también que la contraseña se codifica antes de guardarla para que no tengamos que hacerlo en otra parte de nuestra aplicación.

    Laravel predeterminado Auth/RegisterControllertambién Auth/ResetPasswordControllercodifica la contraseña antes de guardarla en la base de datos, por lo que debemos actualizar el método createy resetPassworden los respectivos controladores después de declarar el mutador anterior.

    Abra el archivo app/Http/Controllers/Auth/RegisterController.phpy agregue el siguiente código.

    /** * Create a new user instance after a valid registration. * * @param  array  $data * @return AppUser */protected function create(array $data){    return User::create([        'name' = $data['name'],        'email' = $data['email'],        'password' = $data['password'],    ]);}

    Abra el archivo app/Http/Controllers/Auth/ResetPasswordController.phpy agregue el siguiente código.

    /** * Reset the given user's password. * * @param  IlluminateContractsAuthCanResetPassword  $user * @param  string  $password * @return void */protected function resetPassword($user, $password){    $user-password = $password;    $user-setRememberToken(Str::random(60));    $user-save();    event(new PasswordReset($user));    $this-guard()-login($user);}

    Para el ResetPasswordController, también necesitará crear alias para las clases respectivas utilizadas antes de la declaración de clase.

    use IlluminateSupportStr;use IlluminateAuthEventsPasswordReset;

    Hemos terminado y nuestra verificación de contraseña funciona como se esperaba.

    Conclusión

    En esta guía, vimos cómo implementar un paso adicional de verificación de contraseña para confirmar que un usuario está autorizado a acceder a un área de administración. Vimos cómo crear y configurar solicitudes de formulario para implementar la validación de formulario dentro de una aplicación Laravel.

    Para obtener más información sobre la validación y las solicitudes de formulario, puede consultar la documentación oficial de Laravel.

    SUSCRÍBETE A NUESTRO BOLETÍN 
    No te pierdas de nuestro contenido ni de ninguna de nuestras guías para que puedas avanzar en los juegos que más te gustan.

    Deja una respuesta

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

    Subir

    Este sitio web utiliza cookies para mejorar tu experiencia mientras navegas por él. Este sitio web utiliza cookies para mejorar tu experiencia de usuario. Al continuar navegando, aceptas su uso. Mas informacion