Skip to main content

Flask Simple Login - Login Extension for Flask

Project description

Travis PyPI PyPI versions PyPI formats Flask

Login Extension for Flask

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

I recommend you to use:

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. Take a look at example.

Hot it works

First install it from PyPI.

pip install flask_simplelogin

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)

Login Screen

Login Screen

Configuring

Simple way

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.

$ export SIMPLELOGIN_USERNAME=chuck
$ export SIMPLELOGIN_PASSWORD=norris

then SimpleLogin will read those env vars automatically.

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

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)

Encrypt passwords

You can use the from werkzeug.security import check_password_hash, generate_password_hash utilities to encrypt passwords.

A working example is available in manage.py of example app

Checking if user is logged in

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

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

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:

{% 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/>`__.

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.

Customizing or translating message alerts

The default message alerts are:

key

message

login_success

login success!

login_failure

invalid credentials

is_logged_in

already logged in

logout

Logged out!

login_required

You need to login first

access_denied

Access Denied

auth_error

Authentication Error: {0}

NOTE: the {0} in auth_error is a required placeholder to pass in the validator error message.

And you can customize by passing a dictionary:

app = Flask(__name__)
messages = {
    'login_success': 'Você está dentro!',
    'login_failure': 'ungültige Anmeldeinformationen',
    'is_logged_in': 'Iam initium',
    'logout': 'Déconnecté!',
    'login_required': 'Devi prima accedere',
    'access_denied': 'Acceso denegado',
    'auth_error': '授權錯誤: {0}'
}
SimpleLogin(app, messages=messages)

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.

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/>`__.

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

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 and of course you can mix SimpleLogin + JWT Simple

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flask_simplelogin-0.0.6.tar.gz (54.6 kB view details)

Uploaded Source

Built Distribution

flask_simplelogin-0.0.6-py2.py3-none-any.whl (17.6 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file flask_simplelogin-0.0.6.tar.gz.

File metadata

File hashes

Hashes for flask_simplelogin-0.0.6.tar.gz
Algorithm Hash digest
SHA256 fa58c5c92746c0c29982bddfe0736fdb3f2256373f555e8529e36f610c815a05
MD5 7ed982b7da5dbe6a84fe71c3eccdf1f9
BLAKE2b-256 a17dbf37a343adae36d33aadcdf8751401c9cfd8901a07d53c5a51a34ab871d2

See more details on using hashes here.

File details

Details for the file flask_simplelogin-0.0.6-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for flask_simplelogin-0.0.6-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 0be2687456d4717bc44d0506e20c0f5eb4f06edd1a31fca379ff4d235199e374
MD5 c56ff71be94c695fa4b5e27f97026210
BLAKE2b-256 30bf533cb931f06d15062d93ccb23c1c3ce87f3ba2b0dae53a7bfd0d0788339f

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page