Rest Api en Flask con JSON Web Token en MySQL o MongoDB

- Andrés Cruz

In english
Rest Api en Flask con JSON Web Token en MySQL o MongoDB

Tokens web JSON

Json Web Token (JWT) es solo un string que enviamos del navegador o cliente a nuestro servidor en el header de la petición o request; y esto con el propósito de validar y verificar al cliente; por supuesto, el servidor es el que se encarga de generar el JWT con alguna condición sobre un usuario existente que generalmente es comprobar una pareja de usuario y contraseña.

Requisitos

Vamos a desarrollar en varias tecnologías como puedes ver, pero para hacer un pequeño resumen, vas a necesitar:

En esta entrada vamos a conocer cómo podemos proteger una Rest Api creada con el paquete de FlaskRestFul con Json Web Token, el famoso JWT empleando el paquete de FlaskJWT empleando por supuesto Flask; además de esto, vamos a emplear el famoso paquete llamado FlaskUser para manejar las credenciales de acceso del usuario; es decir, usuario y contraseña.

Creando los métodos necesarios para trabajar con Flask JWT

En esta sección vamos a ver qué es lo que tenemos que configurar para poder emplear Flask JWT en nuestro proyecto en Flask; por supuesto, estas son configuraciones y desarrollos generales o de ejemplos que lo puedes emplear en cualquier esquema; en nuestro caso, vamos a emplear la el paquete de FlaskUser para manejar todo lo que tenga que ver con el login; en este caso nos interesa la función para manejar las credenciales específicamente el uso del password o contraseña.

Las funciones de identidad y login o autenticación el Flask JWT

Para poder emplear el paquete de FlaskJWT, tenemos que crear en su configuración mínima un par de funciones, la primera para obtener el usuario autenticado dado el identificador, llamada identity y otra función para manejar el login, es decir, comparar el usuario y el password; asi que:

from .models import User, UserBase
from proyect_app import user_manager
 
def autheticate(username, password):
   user = User.objects(username=username).first()
  
   if user_manager.verify_password(password,user):
       userBase = UserBase(user.id, user.username, user.password)
       return userBase
 
def identity(payload):
   user_id = payload['identity']
   user = User.objects(id=user_id).first()
   return user

Función authenticate

Para esta función que recibe por defecto dos parámetros, el usuario y la contraseña, buscamos primero por el usuario y luego verificamos la contraseña, que al emplear FlaskUser la tenemos fácil y podemos comprobar la contraseña mediante la función que nos provee FlaskUser llamada verify_password; a la final, si todo esta ok, retornamos el usuario autenticado.

Función identity

Esta función recibe el payload y nos interesa consumir el ID del usuario que lo tenemos como payload['identity'] y retornar el usuario; así de simple.

Configuraciones globales:

A nivel de nuestro proyecto, tenemos que crear las configuraciones para JWT; viene siendo lo usual y una vez creada las dos funciones anteriores, las importamos y la pasamos como parámetros a la clase correspondiente para Flask JWT:

# jwt
from proyect_app.user.jwt import autheticate, identity
jwt = JWT(app, autheticate, identity)

Las importaciones:

from flask_user import UserManager
from flask_jwt import JWT

Y configuramos nuestro UserManager de nuestro FlaskUser:

user_manager = UserManager(app, db, User)

Configurar la protección en MySQL o MongoDB

Ahora, según el motor de base de datos que estamos empleando, por ejemplo MongoDB con el conector que estamos empleando en nuestro curso de MongoDB con Flask y Django:

db = MongoEngine(app)

o con SQLAlchemy que podemos emplear por ejemplo, MySQL:

db=SQLAlchemy(app)

Definiendo el modelo de Usuario

Para el modelo de usuario, que recuerda que también estamos empleando FlaskUser, lo usual, al menos el usuario y la contraseña: 

import mongoengine as models
from flask_user import UserMixin
  
class User(models.Document, UserMixin):
   active = models.BooleanField(default=True)
 
   # User authentication information
   username = models.StringField(default='')
   password = models.StringField()
 
   # User information
   first_name = models.StringField(default='')
   last_name = models.StringField(default='')
 
   def __str__(self):
       return self.username
 
class UserBase(object):
   def __init__(self, id, username, password):
       self.id = str(id)
       self.username = username
       self.password = password
  
   def __str__(self):
     return f"User id: {self.id}"

La clase de UserBase solamente la tienes que crear si vas a emplear MongoDB para hacer el parseo a json que es empleado internamente por FlaskJWT; simplemente empleamos esta clase como intermediario para devolver el usuario autenticado.

Proteger la Rest Api ful en Flask

Finalmente, protegemos la RestApi en FlaskRestFul; que para modo de ejemplo, tenemos una clase de tipo recurso y le indicamos el decorador correspondiente:

class BookApi(Resource):
   decorators = [jwt_required()]

Puedes encontrar el proyecto completo del curso de Flask con MongoDB en:

Dependencias necesarias o instalaciones

  1. https://pythonhosted.org/Flask-JWT/
  2. https://flask-user.readthedocs.io/en/latest/
  3. https://flask-restful.readthedocs.io/en/latest/
  4. http://docs.mongoengine.org/projects/flask-mongoengine/en/latest/
Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz en Udemy

Acepto recibir anuncios de interes sobre este Blog.