Categories
Python

Making a simple login system with Flask-Login

Flask-Login provides user session management for Flask. It handles the common tasks of logging in, logging out, and remembering your users’ sessions over extended periods of time.

I think Flask-Login is one of the best flask extensions out so far. It makes your pythonistic life a lot easier. With Flask-Login you don’t have to write dozens of session checks and/or redirects for each route. Instead of doing it all manually you just place a @login_required decorator under your route.

Installing Flask-Login

You can simply install Flask-Login by typing pip install flask-login in the command line. If you have problems with installing Flask-Login you can try to install Flask-Login with pip3 or you can try running the command as administrator.

Importing the required modules

For ease, I will give you all the import lines we will need in this tutorial below.

from flask import Flask,render_template,redirect,request
from flask_login import LoginManager, current_user, login_user, logout_user, login_required, UserMixin

That’s all we need.

Initializing the app

After importing the modules we need to initialize Flask and Flask-Login.

app = Flask(__name__)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = 'login' # the login view of your application
app.config['SECRET_KEY'] = "lkkajdghdadkglajkgah" # a secret key for your app

Creating some basic routes

Now we are going to write some basic routes for our login system which create the base of our application.

@app.route('/')
def home():
    return "home: <a href='/login/'&rt;Login</a&rt; <a href='/protected/'&rt;Protected</a&rt; <a href='/logout/'&rt;Logout</a&rt;"

@app.route('/protected/')
def protected():
    return "This page is protected"

@app.route('/login/')
def login():
    return "you are logged in!"

@app.route('/logout/')
def logout():
    return "you are logged out!"

As you see we have four different routes: a main page, a protected page, a login page and a logout page. We probably want to ensure that only authenticated users are able to access the protected page and the logout page. But we also want to avoid that already authenticated users login twice. This isn’t really neccesary but that would be a bit silly.

The user class

A really important part of Flask-Login is the user class which represents your user. Flask-Login provides a UserMixin which makes it easy to create a user class. The constructior of your user class needs to have an identifier which is mostly a username or email.

class User(UserMixin):
  def __init__(self,id):
    self.id = id

The user callback

We also need to provide a user_loader callback. This callback reloads the user from the ID stored in the session. It should take the ID of a user, and return the corresponding user object.

@login_manager.user_loader
def load_user(user_id):
    return User(user_id)

Protecting our application routes

Now we just have a couple things to do. We need to protect the ‘protected’ page and the ‘logout’ page. We also need to make that the login route really does login and that the logout route really does logout. The code will explain itself.

@app.route('/')
def home():
    return "home: <a href='/login/'>Login</a> <a href='/protected/'>Protected</a> <a href='/logout/'>Logout</a>"

@app.route('/protected/')
@login_required
def protected():
    return "protected"

@app.route('/login/')
def login():
    login_user(User(1))
    return "you are logged in"

@app.route('/logout/')
@login_required
def logout():
    logout_user()
    return "you are logged out"

The full code

Here is the full code if you just want to copy it and don’t care about my explanation.

from flask import Flask,redirect,request,session
from flask_login import LoginManager, login_user, logout_user, login_required, UserMixin

app = Flask(__name__)
login_manager = LoginManager()
login_manager.init_app(app)
login_manager.login_view = ''
app.config['SECRET_KEY'] = "lkkajdghdadkglajkgah"

@login_manager.user_loader
def load_user(user_id):
    return User(user_id)

class User(UserMixin):
  def __init__(self,id):
    self.id = id


@app.route('/')
def home():
    return "home: <a href='/login/'>Login</a> <a href='/protected/'>Protected</a> <a href='/logout/'>Logout</a>"

@app.route('/protected/')
@login_required
def protected():
    return "protected"

@app.route('/login/')
def login():
    login_user(User(1))
    return "you are logged in"

@app.route('/logout/')
@login_required
def logout():
    logout_user()
    return "you are logged out"

if __name__ == '__main__':
    app.run(host="0.0.0.0",port=1212,debug=True)