On this article, we’ll have a look at the assorted options that Flask-Login provides and easy methods to use them to create a safe person login performance to your net utility. By the top of this text, you’ll have a great understanding of easy methods to use Flask-Login to implement safe person authentication in your Flask purposes.

Authentication is a vital a part of any net utility that permits customers to entry knowledge or assets because it ensures that solely the suitable folks get entry to delicate data. This will also be achieved in Flask utilizing Flask-Login.

Flask-Login is an extension in Flask with features that deal with the logging in and logging out of customers and hold monitor of the present person(s) all through the applying. This makes it straightforward to implement authentication and authorization in your Flask purposes.

Desk of Contents

Why Use Flask-Login?

Flask-Login has plenty of options and features that make it straightforward to seamlessly carry out authentication in Flask purposes. Listed here are among the advantages of utilizing Flask-Login:

  • Consumer session administration. Flask-Login handles the creation and destruction of person periods. It might additionally retailer the present person’s ID within the session in an effort to simply verify if a person is logged in.

  • Login and logout performance. Flask-Login gives built-in login and logout features. These features deal with all of the vital processes, reminiscent of creating and destroying periods and redirecting the person to the suitable web page.

  • Consumer loader callback. Flask-Login permits you to outline a person loader callback. This callback is used to load the person object for the present session. That is helpful should you’re utilizing a database to retailer person data.

  • Authentication and authorization. Flask-Login makes it straightforward to implement authentication and authorization in your purposes. You need to use Flask-Login to guard particular pages or routes and to grant customers totally different ranges of entry to your utility.

Stipulations

To observe lengthy with this text, you want the next:

  • a information of Python and Flask syntax
  • a primary information of HTML and CSS
  • Python model 3 and Flask put in

Clearly you additionally want entry to an internet browser.

Getting Began

To completely make use of the Flask login module, we have to have Flask-Login and different crucial dependencies put in. These libraries present the mandatory features and instruments wanted to enhance the performance of your app. To put in them, open your command immediate or terminal and execute the next pip command:

pip set up flask-login flask_sqlalchemy flask_bcrypt

Right here’s a breakdown of what every of those libraries is used for:

  • Flask-SQLAlchemy: integrates SQLAlchemy with Flask for database operations
  • Flask-Bcrypt: provides Bcrypt hashing for password safety in Flask

As soon as the set up is accomplished, it would mechanically have the Flask login downloaded within the listing you used.

Word: on the time of writing, there’s a slight situation in resolving the dependencies within the newest model of Flask and Werkzeug. To resolve this, you need to power set up model 2.3.0 of Werkzeug, because it’s the one identified model working proper now.

As soon as your dependencies have been put in, you’ll have to initialize them together with your Flask app:

from flask_sqlalchemy import SQLAlchemy

from flask_login import UserMixin, LoginManager, login_user, logout_user, login_required

from flask_bcrypt import Bcrypt

from flask_login import LoginManager
 app = Flask(__name__)

login_manager = LoginManager()

login_manager.init_app(app)  

Within the code snippet above, we’ve additionally initialized the LoginManager object in our utility. LoginManager is an extension of Flask-Login that’s used to arrange the mandatory configurations for dealing with person periods.

Making a Consumer Mannequin

A mannequin is a illustration of the information construction you wish to use in your utility. It defines how knowledge is organized, saved, and manipulated throughout the system. Fashions are normally used with a database that follows the construction outlined beforehand. For our app, we’ve the next knowledge:

  • a novel ID
  • a username
  • a password (hashed)
class Consumer(UserMixin):

id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(64), distinctive=True)
password_hash = db.Column(db.String(128))

def __repr__(self):
  return f'<Consumer {self.username}>'

You can too add further properties to your person mannequin, reminiscent of an electronic mail handle or profile image, relying on the scope of your venture.

Making a Database

When you’ve outlined your person mannequin, it is advisable to create a database that can retailer the information construction we created within the earlier mannequin.

For this text, we’ll be utilizing an SQLite database. It is because SQLite is a light-weight and serverless database engine. This makes it straightforward to arrange and use, because it doesn’t require a separate set up. It’s additionally a sensible choice for small- to medium-sized purposes.

Right here’s a breakdown of the steps for utilizing an SQLite database in our utility:

  1. To utilize the SQLite database, you need to set a URI in your Flask app configuration. That is normally carried out on the high, alongside different configurations. Right here’s a snippet you need to use:

    app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///website.db' 

    On this snippet, the ///... signifies the relative path to your file — website.db — which is the identify we used for our SQLite database file. This identify could be modified to something you favor.

  2. Subsequent, you need to initialize the Flask-SQLAlchemy ORM utilizing this snippet:

    SQLAlchemy is an object-relational mapper that gives a set of instruments for working with databases utilizing Python. The road db = SQLAlchemy(app) creates an occasion of the SQLAlchemy class and binds it to your Flask utility (app).

  3. To create this database, we’ve to initialize the database, utilizing the create_all technique:

    if __name__ == '__main__':
    
    db.create_all()
    
    app.run(debug=True)

    This code is often positioned on the finish of your Python script or in a separate script devoted to initializing the database. When you run your script, the database file might be created with corresponding tables based mostly on the fashions we outlined beforehand.

    On this case, the code will create a website.db file with a Consumer desk if it doesn’t exist already. The website.db file normally is available in a folder referred to as /occasion/.

    The file structure of our app

Subsequent, we have to create a user_loader that takes a person ID and returns the corresponding Consumer object. Right here’s an instance:

@login_manager.user_loader
def load_user(user_id):
  return Consumer.question.get(user_id)

Password Hashing

Password hashing is a safety measure that shops the cryptographic illustration of the person’s password earlier than it’s saved in a database. This fashion, it turns into harder to get the precise password even when the safety of the applying has been compromised.

Normally, the password is first hashed within the registration course of and saved in a database. Then, every time a person logs in, their password is hashed once more and in comparison with the hashed password saved within the database. If the 2 passwords match, the person is authenticated and given entry to the applying.

Find out how to hash and confirm passwords utilizing Flask-Bcrypt

Flask has an extension referred to as Flask-Bcrypt that helps to realize this performance. It has two main features: generate_password_hash() and check_password_hash().

Thegenerate_password_hash() perform takes the person’s password as an argument and returns a hashed password. That is normally used within the registration logic.

The check_password_hash() perform takes a password and a hashed password as arguments and returns true if the 2 passwords match, or false in the event that they don’t match. That is referred to as earlier than granting entry to the login view

Making a Register View

Views are part of the Flask framework used to generate HTML, JSON, or different knowledge that’s despatched to the person’s browser. On this code snippet, we’re going to create a view that accepts the person’s enter and provides the main points to the database:

@app.route('/register', strategies=['GET', 'POST'])

def  register():

if request.technique == 'POST':
  username = request.kind['username']
  password = request.kind['password']
  hashed_password = bcrypt.generate_password_hash(password).decode('utf-8')

  new_user = Consumer(username=username,password=hashed_password) 
    db.session.add(new_user)
    db.session.commit()
    return redirect(url_for('welcome '))
  return render_template('registeration.html')

Right here’s a breakdown of the code:

  • Within the first line, we outline a route for the URL path /login. This route accepts each GET and POST requests. The login() perform, which is related to the route, might be executed when a request is made.

  • Subsequent, we affirm if the request technique is a POST technique:

    if request.technique == 'POST':

    As soon as it’s confirmed, the perform retrieves the values entered by the person within the login kind:

    username = request.kind['username']
    password = request.kind['password']
  • It then queries the database for a person with the offered username. If a person with the offered username is discovered and the password matches, the code inside this block might be executed.

Making a Login View

Within the login view, we create a logic that accepts enter from a web page after which checks if the enter matches any row within the database:

@app.route('/login', strategies=['GET', 'POST'])

def  login():
  if request.technique == 'POST':
    username = request.kind['username']
    password = request.kind['password']
    person = Consumer.question.filter_by(username=username).first()

    if person and bcrypt.check_password_hash(person.password, password):
    login_user(person)
      return redirect(url_for('welcome'))
  return render_template('login.html')

Right here’s a breakdown of how the code works:

  • Within the first line — @app.route('/login', strategies=['GET', 'POST']): — we’re making use of a decorator that defines a route for the URL path /login. The route accepts each GET and POST requests. The related perform, login(), might be executed when a request is made to this route.

  • The login() perform begins by checking if the request technique is POST:

    if request.technique == 'POST':

    As soon as, it’s confirmed that it’s a POST request, it retrieves the values entered by the person within the login kind:

    username = request.kind['username']
    password = request.kind['password']
  • It then queries the database for a person with the offered username:

    person = Consumer.question.filter_by(username=username).first()
    if person and bcrypt.check_password_hash(person.password, password):  
  • If each the username and the password are validated, the person is granted entry utilizing Flask-Login’s login_user and redirect features:

    login_user(person)
    redirect(url_for('welcome'))
  • Nevertheless, if the request technique isn’t POST or the main points are incorrect, it renders the login.html template:

    return render_template('login.html')

    In essence, it checks if the entered credentials are legitimate, logs the person in, and redirects them to the welcome web page if profitable. If the login is unsuccessful or it’s a GET request, it renders the login template for the person to enter their credentials.

Creating Logout Logic Utilizing a Protected View

In most purposes, some pages are inaccessible if the person isn’t logged in. This contains pages like transaction historical past, drafts, and logout pages. Flask-Login gives a handy method to defend these pages/routes and limit entry to authenticated customers utilizing the login_required decorator. Right here’s a breakdown of the way it works.

To utilize this performance, you need to import the login_required decorator from Flask-Login:

from flask_login import login_required

Subsequent, you need to add the login_required decorator to any route that you just wish to defend. As an illustration, let’s create a logout web page that may solely be accessed when the person is logged in:

@app.route('/logout')
  @login_required
  def  logout():
    logout_user()
    return redirect(url_for('login'))

Right here’s a breakdown of the way it works:

  • Similar to within the login view, @app.route('/logout') defines a route for the URL path /logout.

  • Subsequent, we add a login_required decorator that ensures that the person should be logged in to entry the logout route. If a person isn’t logged in and tries to entry this route, they’ll be redirected to the login web page.

  • Contained in the logout perform, logout_user() known as. This perform is offered by Flask-Login and is used to log the present person out.

  • After logging out the person, the perform redirects them to the login route utilizing redirect(url_for('login')).

So, when a person accesses the /logout route, Flask-Login ensures they’re logged in (@login_required), logs them out, and redirects them to the login web page. This helps to securely deal with person logout in your Flask utility. The login_required decorator is utilized to the /protected route, indicating that solely authenticated customers can entry it. And if a person tries to entry a protected web page with out being logged in, Flask-Login will redirect them to the login web page.

Including Templates

Templates in Flask can help you make use of HTML pages to outline how your website will look. To completely implement the logic in our app.py file, we’re going to create the HTML pages pictured under.

Our app's file structure

The animation under exhibits how the templates render the totally different pages of our website.

You possibly can see the total code for this tutorial and be taught extra about its implementation on this article’s GitHub repository.

How Flask-Login Manages Consumer Periods with Consumer Session Cookies

A person session is a system used to trace and replace person data whereas the person is logged in. Flask-Login manages these periods by storing a session cookie on the person’s browser. The session cookie is a small piece of information that accommodates a novel identifier for the person’s session.

When a person logs in to a web site utilizing Flask-Login, the server generates a session cookie and sends it to the person’s browser. The browser shops the session cookie and contains it in all requests to the server. The server makes use of the session cookie to establish the person and their session state.

For instance, if the person is logged in and visits a web page protected by Flask-Login, Flask-Login will verify the session cookie to see if the person is authenticated. If the person is authenticated, Flask-Login will load the person’s profile data from the database and make it accessible to the view. If the person isn’t authenticated, Flask-Login will redirect the person to the login web page.

When the person logs out of the web site, the server deletes the session cookie from the person’s browser, which terminates the person session.

Conclusion

Flask provides a wide range of features that handle totally different elements of authentication, starting from person session administration to authorization. By making use of those features, you may implement a strong and safe authentication system tailor-made to the particular wants of your utility.