Flask Simple Login - Login Extension for Flask
Project description
Login Extension for Flask
There are 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.
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)
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)
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/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.
Customizing message alerts
app = Flask(__name__)
messages = {
'login_success': 'Great You are in!!',
'login_failure': 'Credenciais inválidas :(',
'is_logged_in': 'You dont need to login again!',
'logout': 'Bye Bye!'
}
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/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
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
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
File details
Details for the file flask_simplelogin-0.0.4.tar.gz
.
File metadata
- Download URL: flask_simplelogin-0.0.4.tar.gz
- Upload date:
- Size: 51.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | 6e5ea93e18e13d12df74e6706e556a227449906967745027ec8ac4ca7db21f40 |
|
MD5 | 2b66d5cf31172c7735108d0ce8ea7d44 |
|
BLAKE2b-256 | 6960f157a2b596c0bfbe805d2a6f8462ae322b6eed1623cea337d1d37ddcbf9b |
File details
Details for the file flask_simplelogin-0.0.4-py2.py3-none-any.whl
.
File metadata
- Download URL: flask_simplelogin-0.0.4-py2.py3-none-any.whl
- Upload date:
- Size: 16.5 kB
- Tags: Python 2, Python 3
- Uploaded using Trusted Publishing? No
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | e23d4e367c8a2ff6d1b5801dfd230b1e2dd12485e0dd259cfdb9515627b333e9 |
|
MD5 | 5aa1cd35d48e6cd86dd12009c0cfa178 |
|
BLAKE2b-256 | 399e9b256717305e0f658f2cef120a132a046a414dc4e97c174aa1fec68a122d |