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:
- Python en alguna versión de la 3.x
- Un ambiente virtual en tu equipo
- MongoDB, puedes emplear perfectamente la terminal o algún cliente
- Postman
- Tu Hola Mundo en Flask, o tener alguna estructura creada
- Saber como crear una Restful en Flask
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
- https://pythonhosted.org/Flask-JWT/
- https://flask-user.readthedocs.io/en/latest/
- https://flask-restful.readthedocs.io/en/latest/
- http://docs.mongoengine.org/projects/flask-mongoengine/en/latest/
Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter