Rest Api in Flask with JSON Web Token in MySQL or MongoDB

- Andrés Cruz

En español

Tokens web JSON

Json Web Token (JWT) is just a string that we send from the browser or client to our server in the request header; and this with the purpose of validating and verifying the client; of course, the server is the one that is in charge of generating the JWT with some condition on an existing user, which is generally checking a pair of username and password.

Requirements

We are going to develop in various technologies as you can see, but to make a short summary, you will need:

In this post we are going to know how we can protect a Rest Api created with the FlaskRestFul package with Json Web Token, the famous JWT using the FlaskJWT package using of course Flask; in addition to this, we are going to use the famous package called FlaskUser to manage the user's access credentials; that is, username and password.

Creating the necessary methods to work with Flask JWT

In this section we are going to see what we have to configure to be able to use the Flask JWT in our Flask project; of course, these are general configurations and developments or examples that you can use in any scheme; in our case, we are going to use the FlaskUser package to handle everything that has to do with the login; in this case, we are interested in the function to manage the credentials, specifically the use of the password.

The identity and login or authentication functions of Flask JWT

In order to use the FlaskJWT package, we have to create a couple of functions in its minimal configuration, the first to obtain the authenticated user given the identifier, called identity and another function to handle the login, that is, compare the user and the password ; so:

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

Authenticate function

For this function that receives two parameters by default, the username and the password, we search first for the user and then we verify the password. By using FlaskUser we have it easy and we can verify the password using the function provided by FlaskUser called verify_password; In the end, if everything is ok, we return the authenticated user.

Function identity

This function receives the payload and we are interested in consuming the user ID that we have as payload['identity'] and returning the user; simple as that

Global Settings:

At our project level, we need to create the configurations for the JWT; It has been the usual and once the two previous functions have been created, we import them and pass them as parameters to the corresponding class for Flask JWT:

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

The Imports:

from flask_user import UserManager
from flask_jwt import JWT

And we set our UserManager to our FlaskUser:

user_manager = UserManager(app, db, User)

Configure protection in MySQL or MongoDB

Now, depending on the database engine that we are using, for example MongoDB with the connector that we are using in our MongoDB with Flask and Django course:

db = MongoEngine(app)

Or with SQLAlchemy that we can use for example, MySQL:

db=SQLAlchemy(app)

Defining the User model

For the user model, which remembers that we are also using FlaskUser, the usual, at least the username and password:

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

You only have to create the UserBase class if you are going to use MongoDB to do the json parsing that is used internally by FlaskJWT; we simply use this class as a go-between to return the authenticated user.

Protect Rest Api ful in Flask

Finally, we protect the Rest Api in Flask RestFul; For example, we have a class of resource type and we indicate the corresponding decorator:

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

You can find the complete project of the Flask with MongoDB course at:

Required dependencies or facilities

  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