Skip to main content
|Travis| |PyPI| |PyPI| |PyPI| |Flask|

Login Extension for Flask
=========================

There are good and recommended options to deal with web authentication &
authorization in Flask.

**I recommend you to use:**

- `Flask-Login <https://flask-login.readthedocs.io>`__
- `Flask-Security <https://pythonhosted.org/Flask-Security/>`__
- `Flask-Principal <https://pythonhosted.org/Flask-Principal/>`__

Those extensions are really complete and **production ready**!

So why **Flask Simple Login**?

However sometimes you need something **simple** for that small project
or for prototyping.

Flask Simple Login
------------------

What it provides:

- Login and Logout forms and pages
- Function to check if user is logged-in
- Decorator for views
- Easy and customizable ``login_checker``
- Basic-Auth for API endpoints

What it does not provide:

- [STRIKEOUT:Database Integration]
- [STRIKEOUT:Password management]
- [STRIKEOUT:API authentication with Token or JWT]
- [STRIKEOUT:Role or user based access control]

of course you can easily implement all above by your own.

Hot it works
------------

First install it from
`PyPI <https://pypi.org/project/flask_simplelogin/>`__.

``pip install flask_simplelogin``

.. code:: python

from flask import Flask
from flask_simplelogin import SimpleLogin

app = Flask(__name__)
SimpleLogin(app)

**That's it!**
--------------

Now you have ``/login`` and ``/logout`` routes in your application.

The username defaults to ``admin`` and the password defaults to
``secret`` (yeah that's not clever, let's see how to change it)

.. figure:: /login_screen.png
:alt: Login Screen

Login Screen

Configuring
-----------

Simple way

.. code:: python

from flask import Flask
from flask_simplelogin import SimpleLogin

app = Flask(__name__)
app.config['SECRET_KEY'] = 'something-secret'
app.config['SIMPLELOGIN_USERNAME'] = 'chuck'
app.config['SIMPLELOGIN_PASSWORD'] = 'norris'

SimpleLogin(app)

That works, but is not so clever, lets use env vars.

.. code:: bash

$ export SIMPLELOGIN_USERNAME=chuck
$ export SIMPLELOGIN_PASSWORD=norris

then ``SimpleLogin`` will read those env vars automatically.

.. code:: python

from flask import Flask
from flask_simplelogin import SimpleLogin

app = Flask(__name__)
app.config['SECRET_KEY'] = 'something-secret'
SimpleLogin(app)

But what if you have more users and more complex auth logic? **write a
custom login checker**

Using a custom login checker
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code:: python

from flask import Flask
from flask_simplelogin import SimpleLogin

app = Flask(__name__)
app.config['SECRET_KEY'] = 'something-secret'


def only_chuck_norris_can_login(user):
""":param user: dict {'username': 'foo', 'password': 'bar'}"""
if user.get('username') == 'chuck' and user.get('password') == 'norris':
return True # <--- Allowed
return False # <--- Denied


SimpleLogin(app, login_checker=only_chuck_norris_can_login)

Checking if user is logged in
-----------------------------

.. code:: python


from flask_simplelogin import is_logged_in

if is_logged_in():
# do things if anyone is logged in

if is_logged_in('admin'):
# do things only if admin is logged in

Protecting your views
---------------------

.. code:: python

from flask_simplelogin import login_required

@app.route('/it_is_protected')
@login_required # < --- simple decorator
def foo():
return 'secret'

@app.route('/only_mary_can_access')
@login_required(username='mary') # < --- accepts a list of names
def bar():
return "Mary's secret"

@app.route('/api', methods=['POST'])
@login_required(basic=True) # < --- Basic HTTP Auth for API
def api():
# curl -XPOST localhost:5000/api -H "Authorization: Basic Y2h1Y2s6bm9ycmlz" -H "Content-Type: application/json"
# Basic-Auth takes base64 encripted username:password
return jsonify(data='You are logged in with basic auth')

class ProtectedView(MethodView): # < --- Class Based Views
decorators = [login_required]
def get(self):
return "only loged in users can see this"

Protecting Flask Admin views
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

.. code:: python


from flask_admin.contrib.foo import ModelView
from flask_simplelogin import is_logged_in


class AdminView(ModelView)
def is_accessible(self):
return is_logged_in('admin')

Customizing templates
---------------------

There are only one template to customize and it is called ``login.html``

Example is:

.. code:: html

{% extends 'base.html' %}
{% block title %}Login{% endblock %}
{% block messages %}
{{super()}}
{%if form.errors %}
<ul class="alert alert-danger">
{% for field, errors in form.errors.items() %}
<li>{{field}} {% for error in errors %}{{ error }}{% endfor %}</li>
{% endfor %}
</ul>
{% endif %}
{% endblock %}

{% block page_body %}
<form action="{{ url_for('simplelogin.login', next=request.args.get('next', '/')) }}" method="post">
<div class="form-group">
{{ form.csrf_token }}
{{form.username.label}}<div class="form-control">{{ form.username }}</div><br>
{{form.password.label}}<div class="form-control"> {{ form.password }}</div><br>
</form>
<input type="submit" value="Send">
</form>
{% endblock %}

Take a look at the `example
app <https://github.com/rochacbruno/flask_simplelogin/blob/master/example/app.py>`__.

And you can customize it in anyway you want and need, it receives a
``form`` in context and it is a ``WTF form`` the submit should be done
to ``request.path`` which is the same ``/login`` view.

You can also use ``{% if is_logged_in %}`` in your template if needed.

Custom validators
-----------------

Pass ``must`` argument to ``login_required`` decorator, it can be a
``function`` or a list of ``functions`` if function returns ``None``
means **No** error and validator passed. if function returns an
``"Error message"`` means validator did not passed.

.. code:: python

def be_admin(username):
"""Validator to check if user has admin role"""
user_data = my_users.get(username)
if not user_data or 'admin' not in user_data.get('roles', []):
return "User does not have admin role"


def have_approval(username):
"""Validator: all users approved so return None"""
return


@app.route('/protected')
@login_required(must=[be_admin, have_approval])
def protected():
return render_template('secret.html')

Take a look at the `example
app <https://github.com/rochacbruno/flask_simplelogin/blob/master/example/app.py>`__.

Requirements
------------

- Flask-WTF and WTForms
- ``SECRET_KEY`` set in your ``app.config``

Integrations
------------

Do you need Access Control? you can easily mix ``flask_simplelogin`` with ``flask_allows``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

https://github.com/justanr/flask-allows ``pip install flask_allows``

.. code:: python

from flask import Flask, g
from flask_simplelogin import SimpleLogin
from flask_allows import Allows

app = Flask(__name__)
app.config['SECRET_KEY'] = 'something-secret'


def is_staff(ident, request):
return ident.permlevel == 'staff'

def only_chuck_norris_can_login(user):
if user.get('username') == 'chuck' and user.get('password') == 'norris':
# Bind the logged in user data to the `g` global object
g.user.username = user['username']
g.user.permlevel = 'staff' # set user permission level
return True # Allowed
return False # Denied

# init allows
allows = Allows(identity_loader=lambda: g.user)

# init SimpleLogin
SimpleLogin(app, login_checker=only_chuck_norris_can_login)

# a view which requires a logged in user to be member of the staff group
@app.route('/staff_only')
@allows.requires(is_staff)
@login_required
def a_view():
return "staff only can see this"

Need JSON Web Token (JWT)?
~~~~~~~~~~~~~~~~~~~~~~~~~~

Take a look at
`Flask-JWT-Simple <https://github.com/vimalloc/flask-jwt-simple>`__ and
of course you can mix SimpleLogin + JWT Simple

.. |Travis| image:: https://img.shields.io/travis/rochacbruno/flask_simplelogin.svg?style=flat-square
:target: https://travis-ci.org/rochacbruno/flask_simplelogin
.. |PyPI| image:: https://img.shields.io/pypi/v/flask_simplelogin.svg?style=flat-square
:target: https://pypi.org/project/flask_simplelogin/
.. |PyPI| image:: https://img.shields.io/pypi/pyversions/flask_simplelogin.svg?style=flat-square
:target:
.. |PyPI| image:: https://img.shields.io/pypi/format/flask_simplelogin.svg?style=flat-square
:target:
.. |Flask| image:: https://img.shields.io/badge/Flask-Extension-blue.svg?style=flat-square
:target:

Metadata

Release files for flask_simplelogin 0.0.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for flask_simplelogin 0.0.2
File Size Uploaded
flask_simplelogin-0.0.2.tar.gz 50.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for flask_simplelogin 0.0.2
File Interpreter ABI Platform
flask_simplelogin-0.0.2-py2.py3-none-any.whl Python 3, Python 2 none any Details

Total release size: 66.6 kB

Release files / flask_simplelogin-0.0.2.tar.gz

Download URL flask_simplelogin-0.0.2.tar.gz
Size 50.6 kB
Tags Source
SHA-256 checksum
How to use checksums
20d67eb3014892d13140e071e9b1fae005112ee18ac8efdd2944be323988f11a
BLAKE2b-256 checksum
How to use checksums
d536d892ddabba748bc12c0fbb4c004ff163e9adc429aa6f7bb034c9de259819
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release files / flask_simplelogin-0.0.2-py2.py3-none-any.whl

Download URL flask_simplelogin-0.0.2-py2.py3-none-any.whl
Size 16.0 kB
Tags Python 2 Python 3
SHA-256 checksum
How to use checksums
080491c549f51258251742791708ed6cec036e02565ee146f10576d109e2d9c1
BLAKE2b-256 checksum
How to use checksums
757e080bdc14d323f53ba7899523e23efc2614fc61c5c0af9128554f745dbccd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No

Release history Release notifications | RSS feed

0.3.0

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.4

2 release files

0.0.3

2 release files

This release

0.0.2 This release

2 release files

0.0.1

2 release files

0.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page