Authentication with Flask-Login

Cho Zin Thet
4 min readSep 29, 2021
auth (vecteezy image)

Authentication is a basic security for website. Difference between Authentication and Authorization is, Authentication is how user can pass to our website. For example, if user want to use our website, user need to register or login to our website. Authorization is permission for different type of user. For example, this user is admin type or member or user.

There are many authentication ways to use each website. Two Factor Authentication, Session Based Authentication, Token Based Authentication and so on. With flask app, we can use Flask-Login. It is based on session authentication and you can test flask-login as below.

get all code on github

User Table

sqlite database

Simple Register Form

  • RegisterForm ()pass to register template when GET request come
  • check user email
  • if not exist, create new user and add to database
  • if exist, show flash messages
@app.route("/register", methods=['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
email = form.email.data
password = form.password.data
if User.query.filter_by(email=email).first():
flask.flash("user has already registered")
else:
# create new user
new_user = User(
email = email,
password = generate_password_hash(password, method='pbkdf2:sha256', salt_length=8)
)
db.session.add(new_user)
db.session.commit()
login_user(new_user)
return redirect(url_for('home'))

return render_template("register.html", form=form)

Simple Login Form

  • LoginForm()pass to login template when GET request come
  • check user email
  • if exist check password
  • if True, go to home route
  • if False, show flash messages
@app.route("/", methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
email = form.email.data
password = form.password.data
user = User.query.filter_by(email=email).first()
if user:
if password == user.password:
return redirect(url_for('home'))
else:
flask.flash("incorrect password")
else:
flask.flash("user not found")

return render_template("login.html", form=form)

Flask Login

As above code, user can go other routes without login or register. So we have to lock other routes and check user has authenticated. Flask Login make it easy with session authentication.

  • if user login or register successfully, flask login store user id in session and return session id to browser and then browser store in cookies.
  • from that time, user go to our flask app, flask login check session id in browser cookies with user id in session.
  • flask-login manage user login such as login required, is actived, is authenticated and so on.

Let’s use flask-login in our user authentication -

  1. install
pip install flask-login

2. import

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

3. LoginManager

Code in LoginManager class let our flask app to work with flask-login. Next, we need to create SECRET_KEY for session authentication.

user_loader function reload user object from user id in session.

app.config['SECRET_KEY'] = "thisissecret"login_manager = LoginManager()
login_manager.init_app(app)
@login_manager.user_loader
def load_user(id):
return User.query.get(int(id))

4. UserMixin

When creating User table, you have to inherit UserMixin class to use current user property.

class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True)
email = db.Column(db.String(100), nullable=False, unique=True)
password = db.Column(db.String(100), nullable=False)

5. login_user

After user has authenticated, login_user function store user_id in session.

@app.route("/", methods=['GET', 'POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
email = form.email.data
password = form.password.data
user = User.query.filter_by(email=email).first()
if user:
if check_password_hash(user.password, password):
login_user(user)
return redirect(url_for('home'))
else:
flask.flash("incorrect password")
else:
flask.flash("user not found")

return render_template("login.html", form=form)


@app.route("/register", methods=['GET', 'POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
email = form.email.data
password = form.password.data
if User.query.filter_by(email=email).first():
flask.flash("user has already registered")
else:
# create new user
new_user = User(
email = email,
password = generate_password_hash(password, method='pbkdf2:sha256', salt_length=8)
)
db.session.add(new_user)
db.session.commit()
login_user(new_user)
return redirect(url_for('home'))

return render_template("register.html", form=form)
login user function create session data

6. login_required

login required decorator function check user has authenticated or not.

@app.route("/home")
@login_required
def home():
return render_template("home.html")
login required decorator function

7. current_user properties

@app.route("/home")
@login_required
def home():
print(current_user.is_authenticated)
print(current_user.is_active)
return render_template("home.html")
User Mixin class

8. logout_user

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

--

--