2

EXPLICACIÓN DE LA CLASE NÚMERO 29

<h1>EXPLICACIÓN DE LA CLASE 29</h1>

Hago esta pequeña explicación por si sintieron (como yo) que esta clase estuvo un poco más difícil de entender.
¿Qué queremos lograr en esta clase?

  1. Queremos proteger nuestra ruta 127.0.0.0:3000/hello para que la única forma de acceder a ella sea llenando primero el formulario.

  2. Queremos crear un objeto (instancia de una clase llamada UserModel) para guardar ahí la información más relevante sobre el usuario que está intentando iniciar sesión (Si no entiendes ya te explico).
    Luego ese objeto UserModel nos servirá para autenticar la información que el usuario está metiendo en el formulario.

  3. Creamos la función load_user() que será la que active la función query (Mas abajo hablo de ella).

Ojo: En esta clase del curso aún no autenticaremos la información (usuario y contraseña) que el usuario ingresó en el formulario.

<h1></h1>

Primero (Proteger la ruta)

En el archivo init.py de nuestra app importamos el administrador de login.
(Login_Manager contiene el codigo para que mi app y flask_login funcionen juntos)

    from flask_login import LoginManager
<h1></h1>

Creamos una instancia de LoginManager

    login_manager = LoginManager()
<h1></h1>

Indicamos la vista o ruta que lleva a nuestro formulario.
(recordemos que el formulario en este caso lo manejamos como un Blueprint, osea que es como si fuese una “mini-app” conectada y dependiente a nuestra app principal)

    login_manager.login_view = 'auth.login'
<h1></h1>

Esta siguiente linea va dentro de la función create_app() su objetivo es que el LoginManager tenga el poder de inicializar nuestra app. Lo ponemos debajo de la instancia de la app
(app = Flask(name))

login_manager.init_app(app)
<h1></h1>

Ahora ponemos el decorador @login_required en las rutas del main .py que nosotros queremos proteger con el formulario.

@app.route('/hello', methods=['GET'])@login_required #Decorador para proteger la rutadefhello():pass
<h1></h1>

Segundo (Crear el UserModel)

CONTEXTO: Una vez usuario acaba de ingresar unos datos en el formulario nosotros necesitamos verificar si esos datos son válidos o no.
Para realizar la verificación necesitamos el ID del usuario que nos permitirá consultar la base de datos ¿Qué estamos consultando?, pues la contraseña, porque el usuario ya lo tenemos (recordar que en este proyecto el docente decidió usar el mismo username como ID)

<h1></h1>

Entonces, primero el usuario mete los datos en el formulario y como nosotros estamos usando el usuario como ID, agarramos ese nombre de usuario para pasárselo como parámetro a una función get_user(user_id) que recibe ese id para realizar una consulta en la base de datos.

<h1></h1>

Ahora sí…

<h1></h1>

Creamos un nuevo archivo llamado models .py el cual contendrá lo necesario para realizar consultas a la base de datos (que nosotros estamos manejando en el archivo firestore_service.py) y almacenar lo obtenido de esa consulta en una clase UserData

<h1></h1>

Primero importamos lo que necesitamos:
UserMixin nos servirá para heredar métodos genéricos que son importantes para flask_login.

<h1></h1>

get_user es una función que necesita que le pasemos como parámetro un ID para que ese ID pueda hacer una consulta a la base de datos (lo que está consultado es el documento del user, porque como ya saben Firestore funciona con documentos).

from flask_login import UserMixin
from .firestore_service import get_user
<h1></h1>

Creamos una clase UserData que será como un “almacén” donde guardaremos los datos que vamos a traernos de la base de datos

classUserData():"""
        Estos son los datos obtenidos en la consulta a la db
        Luego se los vamos a pasar al UserModel para que cree 
        un objeto del usuario actual y realizar autenticación

        Hacemos esta clase para asegurarnos de que siempre tenemos la info que
        el UserModel necesita (Username y Password)
    """def__init__(self, username, password):
        self.username = username
        self.password = password

Ahora creamos la clase UserModel: Esta clase sirve para mas adelante autenticar la información que el usuario metió al formulario, mantener al usuario registrado en la sesión actual y usar los datos que le pasamos desde UserData en el contenido que le mostramos al usuario.

<h1></h1>

Pero ahorita lo que más nos interesa de esta clase es el método query() la cual recibe como parámetro el ID del usuario.

classUserModel(UserMixin):def__init__(self, user_data):
        self.id = user_data.username 
        self.password = user_data.password
@staticmethod defquery(user_id):
        user_doc = get_user(user_id) #Aquí se hace la petición a la db#Ahora pasamos los datos consultados a una instancia de UserData
        user_data = UserData(
        	username=user_doc.id, 
                password=user_doc.to_dict()['password']
                )
# Por ultimo retornamos una instancia del UserModel pasándole el UserData que ya tiene datos cargados.return UserModel(user_data)

Al final tenemos un UserModel con datos cargados desde la base de datos preparado para realizar la autenticación del password que el usuario puso en el formulario.

<h1></h1>

ACLARACIONES: Las clases de UserData y UserModel son arrancadas por el método query() dentro de UserModel (Osea que esa función empieza todo)

<h1></h1>

Tercero

Ahora vamos a crear una función load_user en el archivo init.py de la app el cual recibe como parámetro un ID

<h1></h1>
@login_manager.user_loaderdefload_user(username_id):#Ten en mente este username_id más abajo te explico de donde lo sacamos."""
    Esta funcion recibe un ID  y retorna un user_object
    """return UserModel.query(username_id) 

Como ves hay que ponerle un decorador @login_manager.user_loader el cual por debajo lo que hace es tomar la función load_user guardarla en una variable llamada _self.user_callback y luego vuelve a retornar la función load_user

¿Para qué hacemos eso?
Debo decirte que al momento de escribir esto no he visto la clase siguiente pero, viendo en la documentación, dice que hay una función llamada _load_user() usada por el LoginManager la cual se encarga de tomar el ID del usuario desde sessions, luce así:

Link a la documentación

#Extracto de la documentacióndef_load_user(self):# Load user from Flask Session
        user_id = session.get('user_id')  # Obtiene el ID de una sessionif user_id isnotNoneand self._user_callback isnotNone:
            user = self._user_callback(user_id)

¿Recuerdas que la variable _self.user_callback tiene nuestra función load_user(username_id)?

user= self._user_callback(user_id) 
#Significa que en esta linea le estamos mandando el Username_id que necesitábamos para arrancar

Entonces el ID en principio lo tendríamos que guardar en session[‘user_id’] a menos que el docente lo haga de otra forma.

<h1></h1>

Ojo: Como viste, aún no hemos realizado ninguna autenticación, supongo que eso lo haremos en clases siguientes.

<h1></h1>

Espero que te haya servido, si tienes algún aporte déjalo abajo para facilitar el aprendizaje de esta clase en particular que estaba un poco más difícil de comprender.

Escribe tu comentario
+ 2