Hi there guys! In this post I will share my experience with you while developing a Flask app with login functionality. The sourcecode of the app is available here.
We will be using the following libraries:
- Flask (obviously)
- Flask-SQLAlchemy
- Jinja2
- SQLAlchemy
- Werkzeug
- Flask-WTF
First-of-all we will define a User model. It goes something like this:
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(120))
password = db.Column(db.String(120))
email = db.Column(db.String(240))
def __init__(self, name, email, password):
self.name = name
self.email = email
self.set_password(password)
def set_password(self, password):
self.password = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password, password)
def __repr__(self):
return '<User %r>' % self.name
We did a couple of things here. They are:
- Assigned
user
as the tablename - created 4 fields with
id
as the primary_key - created 2 custom methods,
set_password
andcheck_password
. - Modified the output of
__repr___
to make it more user-friendly
The 2 custom methods allow us to save password hashes instead of plain-text passwords. Always make sure that you save only the hashes and not the plain-text passwords so that if you database is somehow compromized, the plain-text passwords are not leaked.
There are four views in my app. Namely:
- home
- login
- signup
- logout
###home
:
This route simply redirects to the login
view if the user is not logged in. We check that the user is logged in or not by running the following code:
if session['user_name']:
This only runs if there is a user_name
key in the session dict. So if there is not user_name
in the session dict we simply redirect the user to login by running this code:
return redirect(url_for('login'),401)
401 stands for un-authorized. This status code tells the user that he is not authorized to view this page.
###login
:
In this view we create an instance of the LoginForm
and present it to the user if he is not logged in. If the user submits the form correctly and a user with the email specified exists in our server, we redirect the user to the home
view. We check that the user_email is in the database and the password is correct by running the following code:
user = User.query.filter_by(email=form.email.data).first()
if user is not None and user.check_password(form.password.data):
If it is correct then we modify the session variables by running this code:
session['user_email'] = form.email.data
session['user_name'] = user.name
If it is incorrect then we present the errors to the user and ask him/her to try again.
###signup
:
This view is kind-of similar to the login view. In this view we create an instance of the SignupForm
form and present it to the user. If the form is validated on submit then we create a user in our database with the supplied information.
Finally, we redirect the user to the home view.
###logout
:
This view simply pops the user_name
and user_email
values from the session
dict.
There is one other decorated method as well. It is check_user_status
. It is called before every request. It allows us to modify a couple of variables to our liking. We use it to modify the session
variable.
The key here is the session
dict. We use it to check whether the user is logged-in or not. I hope you enjoyed this short intro. You can always checkout the whole source-code of the app.py
file from the project to get a better understanding.