Authorization and Authentication-Restrict access to protected routes with Python, Flask and Flask Login

Python Code Nemesis
Code Like A Girl
Published in
6 min readMay 22, 2023

--

Photo by Chris Ried on Unsplash

Introduction

Authentication and authorization are two closely related but distinct concepts in the context of security and access control. In this article, we will go through authentication and authorization and their key differences. We will use Flask login to create a login-based application to restrict access to selected routes.

Authentication

Authentication refers to the process of verifying the identity of a user, application, or device. It involves establishing the authenticity of a user’s credentials, such as a username and password, or using other forms of authentication, such as biometric authentication or multi-factor authentication. Authentication ensures that the user or application is who they claim to be and helps prevent unauthorized access to resources.

Authorization

Authorization, on the other hand, refers to the process of granting or denying access to resources based on the authenticated identity of the user or application. It involves defining access control policies that specify what actions a user or application is allowed to perform on a resource, based on their identity and permissions. Authorization ensures that users or applications only have access to the resources they are authorized to access and helps enforce the principle of least privilege.

In summary, authentication is the process of verifying a user’s identity, while authorization is the process of granting or denying access to resources based on that identity. Authentication establishes who a user is, while authorization determines what they are allowed to do.

Flask Login

Time to do it yourself! Let’s look at authentication and authorization with Python and Flask. Create a new project directory for your application. Create a file called app.py and enter the following code:

# Import the Flask and Flask-Login libraries
from flask import Flask, render_template, request, session, redirect
from flask_login import LoginManager, UserMixin, login_user, logout_user, current_user, login_required

# Create a Flask app
app = Flask(__name__)
app.secret_key = '89798789jhvjhjg'

# Configure Flask-Login
login_manager = LoginManager()
login_manager.init_app(app)

# Define a User model
class User(UserMixin):
def __init__(self, username, password):
self.username = username
self.password = password

def get_id(self):
return self.username

@login_manager.user_loader
def load_user(user_id):
return user if user.get_id() == user_id else None


# Create a user
user = User('admin', 'password')

# Register the user with Flask-Login
login_manager.user_loader(load_user)

@app.route('/login', methods=['GET', 'POST'])
def login():
if current_user.is_authenticated:
return redirect('/protected')

if request.method == 'POST':
# Get the username and password from the request
username = request.form['username']
password = request.form['password']

# Check if the username and password are valid
if user.username == username and user.password == password:
# Login the user
login_user(user)
return redirect('')

# Otherwise, show an error message
return render_template('login.html', error='Invalid username or password.')

# Render the login form for GET requests
return render_template('login.html')

# Define a route for the logout page
@app.route('/logout')
def logout():
# Logout the user
logout_user()
return redirect('/')

# Define a protected route
@app.route('/protected')
@login_required
def protected():
return render_template('protected.html')

# Run the app
if __name__ == '__main__':
app.run(debug=True)

This code will create a simple Flask app with two routes: a login page and a protected page. The login page will allow users to log in with a username and password. The protected page will only be accessible to logged-in users.

Let’s go through the main components and their functionalities:

Creating the Flask app:

  • An instance of the Flask application is created.
  • The app.secret_key attribute is set to a random value. This key is used for securely signing the session cookie.

Configuring Flask-Login:

  • An instance of LoginManager is created.
  • The init_app() method is called with the Flask app instance to initialize Flask-Login.

Defining the User model:

  • The User class is defined, which represents the user model.
  • The class inherits from UserMixin, which provides default implementations for some of the required methods by Flask-Login.
  • The get_id() method is defined, which returns the unique identifier for the user.

Implementing the user_loader callback:

  • The load_user function is defined as the user_loader callback.
  • This function is responsible for loading the user object based on the user ID.
  • It checks if the provided user ID matches the user’s ID and returns the user object or None accordingly.

Creating a user:

  • An instance of the User class is created, representing a specific user.
  • This is just a sample user for demonstration purposes.

Registering the user with Flask-Login:

  • The load_user function is registered as the user_loader callback for Flask-Login.
  • This tells Flask-Login how to load the user object based on the user ID.

Defining the login route:

  • The /login route is defined with the @app.route decorator.
  • It handles both GET and POST requests.
  • GET requests render the login form, while POST requests process the form submission for user login.

Handling user authentication in the login route:

  • If a POST request is received (i.e., form submission), it retrieves the username and password from the request data.
  • It checks if the provided credentials match the user’s credentials.
  • If the credentials match, the user is logged in using the login_user function, and the user is redirected to a protected page (/protected).

Defining the logout route:

  • The /logout route is defined to handle user logout.
  • It logs out the currently logged-in user using the logout_user function and redirects the user to the home page ('/login').

Defining the protected route:

  • The /protected route is defined as a protected route that requires authentication.
  • The @login_required decorator ensures that only authenticated users can access this route.
  • If a user is authenticated, the protected page is rendered.

Running the Flask app:

  • The app is run using app.run() with the debug mode enabled.

To use this code, you will need to have Python and Flask installed. Once you have installed Python and Flask, you can create a new directory and save the code above in a file called app.py. Then, you can run the app with the following command:

python app.py

Once the app is running, you can visit the following URLs in your web browser:

  • http://localhost:5000/login - This will load the login page.
  • http://localhost:5000/protected - This will redirect you to the login page if you are not logged in. If you are logged in, you will be able to view the protected route.

Test your application

Enter the username and password in the login page.

If you enter the incorrect credentials, you will see an error messge on the login page:

Error message :

Access the protected Route

Next, enter the correct credentials. Once you are successfully logged in, you can access the protected page:

That’s it! Your application has login and logout functionality now. Only admin users can access the protected route! Perfect!

All the code for this is available on Github:

That’s it for this article! Feel free to leave feedback or questions in the comments. If you found this an exciting read, leave some claps and follow! I love coffee, so feel free to buy me a coffee at https://paypal.me/pythoncodenemesis XD. Cheers!

--

--