Table of Contents
- Introduction
- Prerequisites
- Installing Flask-Security
- Configuring Flask-Security
- Adding User Registration
- Creating Login Functionality
- Protecting Routes
- Conclusion
Introduction
In this tutorial, you will learn how to enhance the security features of your Flask application using Flask-Security. Flask-Security is a powerful extension that provides a quick and easy way to add authentication, authorization, and other security features to your Flask web application.
By the end of this tutorial, you will be able to:
- Install and configure Flask-Security in your Flask app.
- Implement user registration and login functionality.
- Protect certain routes in your application based on user roles and permissions.
Before we get started, make sure you have a basic understanding of Python and Flask. It is also recommended to have Python and Flask installed on your machine.
Prerequisites
To follow along with this tutorial, you need to have the following prerequisites:
- Python installed on your machine
- Flask framework installed (you can install it using
pip install flask
)
Installing Flask-Security
Flask-Security can be installed using pip
. Open your terminal or command prompt and run the following command:
bash
pip install Flask-Security
Configuring Flask-Security
To use Flask-Security in your Flask app, you need to configure it with some basic settings. Create a new file called config.py
in your project directory and add the following code:
```python
# config.py
# Flask-Security config
SECRET_KEY = 'your-secret-key-goes-here'
SECURITY_PASSWORD_SALT = 'your-password-salt-goes-here'
``` Make sure to replace `'your-secret-key-goes-here'` and `'your-password-salt-goes-here'` with your actual secret key and password salt. These values should be kept secret and unique for your application.
Adding User Registration
To add user registration functionality to your Flask app, you need to create a registration form and handle the form submission. Here’s an example of how you can achieve this:
- Create a new file called
forms.py
in your project directory with the following code:# forms.py from flask_wtf import FlaskForm from wtforms import StringField, PasswordField from wtforms.validators import DataRequired, Email class RegistrationForm(FlaskForm): email = StringField('Email', validators=[DataRequired(), Email()]) password = PasswordField('Password', validators=[DataRequired()])
- In your main Flask application file (e.g.,
app.py
), import the necessary modules and add the following code:# app.py from flask import Flask, render_template, redirect, url_for from flask_security import Security, SQLAlchemyUserDatastore, login_required from flask_wtf.csrf import CSRFProtect from flask_wtf.csrf import CSRFError from forms import RegistrationForm from models import db, User, Role app = Flask(__name__) app.config.from_pyfile('config.py') csrf = CSRFProtect(app) db.init_app(app) user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = Security(app, user_datastore) @app.route('/') def home(): return 'Welcome to the Flask App' @app.route('/register', methods=['GET', 'POST']) def register(): form = RegistrationForm() if form.validate_on_submit(): user = user_datastore.create_user(email=form.email.data, password=form.password.data) db.session.commit() return redirect(url_for('home')) return render_template('register.html', form=form)
- Create a template file called
register.html
in a new folder calledtemplates
. Add the following code to theregister.html
file:<!-- templates/register.html --> {% extends 'base.html' %} {% block content %} <h1>Register</h1> <form method="POST" action="{{ url_for('register') }}"> {{ form.csrf_token }} {{ form.email.label }} {{ form.email() }}<br><br> {{ form.password.label }} {{ form.password() }}<br><br> <input type="submit" value="Register"> </form> {% endblock %}
You can now run your Flask app using
flask run
command and visithttp://localhost:5000/register
to see the registration form.
Creating Login Functionality
To add login functionality to your Flask app, you need to create a login form and handle the login submission. Here’s an example of how you can achieve this:
- Create a new file called
forms.py
in your project directory with the following code:# forms.py from flask_wtf import FlaskForm from wtforms import StringField, PasswordField from wtforms.validators import DataRequired class LoginForm(FlaskForm): email = StringField('Email', validators=[DataRequired()]) password = PasswordField('Password', validators=[DataRequired()])
- In your main Flask application file (e.g.,
app.py
), import the necessary modules and add the following code:# app.py from flask import Flask, render_template, redirect, url_for from flask_security import Security, SQLAlchemyUserDatastore, login_required from flask_wtf.csrf import CSRFProtect from flask_wtf.csrf import CSRFError from forms import LoginForm from models import db, User, Role app = Flask(__name__) app.config.from_pyfile('config.py') csrf = CSRFProtect(app) db.init_app(app) user_datastore = SQLAlchemyUserDatastore(db, User, Role) security = Security(app, user_datastore) @app.route('/') def home(): return 'Welcome to the Flask App' @app.route('/login', methods=['GET', 'POST']) def login(): form = LoginForm() if form.validate_on_submit(): user = user_datastore.get_user(email=form.email.data) if user and user_datastore.verify_password(form.password.data, user.password): return redirect(url_for('home')) return render_template('login.html', form=form)
- Create a template file called
login.html
in thetemplates
folder. Add the following code to thelogin.html
file:<!-- templates/login.html --> {% extends 'base.html' %} {% block content %} <h1>Login</h1> <form method="POST" action="{{ url_for('login') }}"> {{ form.csrf_token }} {{ form.email.label }} {{ form.email() }}<br><br> {{ form.password.label }} {{ form.password() }}<br><br> <input type="submit" value="Login"> </form> {% endblock %}
You can now run your Flask app using
flask run
command and visithttp://localhost:5000/login
to see the login form.
Protecting Routes
Flask-Security provides a convenient way to protect certain routes in your Flask app based on user roles and permissions. Here’s an example of how you can achieve this:
- In your
app.py
file, add the following code after the import statements:# app.py # Existing code... @app.route('/protected') @login_required def protected(): return 'You are in a protected route! Only authenticated users can access this.' @app.errorhandler(CSRFError) def handle_csrf_error(e): return 'CSRF token missing or incorrect.', 400 if __name__ == '__main__': app.run()
- Update the
home
route in yourapp.py
file as follows:# app.py @app.route('/') @login_required def home(): return 'Welcome to the Flask App'
Now, if you try to access the home route
http://localhost:5000/
, you will be redirected to the login page first. After successfully logging in, you will be able to access the protected route athttp://localhost:5000/protected
.
Conclusion
In this tutorial, you learned how to enhance the security features of your Flask application using Flask-Security. You installed and configured Flask-Security, added user registration and login functionality, and protected specific routes based on user authentication. Flask-Security provides a convenient way to implement authentication and authorization in Flask web applications, making it easier to develop secure applications.
You can further explore Flask-Security’s documentation to discover additional features and customization options to create even more secure web applications.