The Authentication class provides a means of authenticating users of the site. It is designed to work out-of-the-box with a simple User model, but can be heavily customized.
The auth system is also designed to work closely with the Admin Interface.
In order to provide a method for users to authenticate with your site, instantiate an Auth backend for your project:
from flask import Flask
from flaskext.auth import Auth
from flaskext.db import Database
app = Flask(__name__)
db = Database(app)
# needed for authentication
auth = Auth(app, db)
If you want to mark specific areas of your site as requiring auth, you can decorate views using the Auth.login_required() decorator:
@app.route('/private/')
@auth.login_required
def private_timeline():
user = auth.get_logged_in_user()
# ... display the private timeline for the logged-in user
If the request comes from someone who has not logged-in with the site, they are redirected to the Auth.login() view, which allows the user to authenticate.
Whenever in a request context, the currently logged-in user is available by calling Auth.get_logged_in_user(), which will return None if the requesting user is not logged in.
The auth system also registers a pre-request hook that stores the currently logged-in user in the special flask variable g.
The auth system registers a template context processor which makes the logged-in user available in any template:
{% if user %}
<p>Hello {{ user.username }}</p>
{% else %}
<p>Please <a href="{{ url_for('auth.login') }}?next={{ request.path }}">log in</a></p>
{% endif %}
It is easy to use your own model for the User, though depending on the amount of changes it may be necessary to override methods in both the Auth and Admin classes.
Here’s a simple example of extending the auth system to use a custom user model:
app = Flask(__name__)
db = Database(app)
# create our custom user model
class User(db.Model):
username = CharField()
password = CharField()
email = CharField()
# ... our custom fields ...
is_superuser = BooleanField()
# create a modeladmin for it
class UserAdmin(ModelAdmin):
columns = ('username', 'email', 'is_superuser',)
# subclass Auth so we can return our custom classes
class CustomAuth(Auth):
def get_user_model(self):
return User
def get_model_admin(self):
return UserAdmin
# instantiate the auth
auth = CustomAuth(app, db)
Here’s how you might integrate the custom auth with the admin area of your site:
# subclass Admin to check for whether the user is a superuser
class CustomAdmin(Admin):
def check_user_permission(self, user):
return user.is_superuser
# instantiate the admin
admin = CustomAdmin(app, auth)
admin.register(User, UserAdmin)
admin.setup()
The Auth system is comprised of a single class which is responsible for coordinating incoming requests to your project with known users. It provides the following:
All of these pieces can be customized, but the default out-of-box implementation aims to provide a good starting place.
So, without further ado here’s a look at the auth class:
Parameters: |
|
---|
Return type: | returns the currently logged-in User, or None if session is anonymous |
---|
Note
this method must be called while within a RequestContext
Parameters: | func – a view function to be marked as login-required |
---|---|
Return type: | if the user is logged in, return the view as normal, otherwise returns a redirect to the login page |
Note
this decorator should be applied closest to the original view function
@app.route('/private/')
@auth.login_required
def private():
# this view is only accessible by logged-in users
return render_template('private.html')
Return type: | Peewee model to use for persisting user data and authentication |
---|
Parameters: | model_admin – subclass of ModelAdmin to use as the base class |
---|---|
Return type: | a subclass of ModelAdmin suitable for use with the User model |
Note
the default implementation includes an override of the ModelAdmin.save_model() method to intelligently hash passwords:
class UserAdmin(model_admin):
columns = ['username', 'email', 'active', 'admin']
def save_model(self, instance, form, adding=False):
orig_password = instance.password
user = super(UserAdmin, self).save_model(instance, form, adding)
if orig_password != form.password.data:
user.set_password(form.password.data)
user.save()
return user
Return type: | a tuple of 2-tuples mapping url to view function. |
---|
Note
the default implementation provides views for login and logout only
def get_urls(self):
return (
('/logout/', self.logout),
('/login/', self.login),
)
Return type: | a wtforms.Form subclass to use for retrieving any user info required for login |
---|
Given the username and password, retrieve the user with the matching credentials if they exist. No exceptions should be raised by this method.
Return type: | User model if successful, otherwise False |
---|
Mark the given user as “logged-in”. In the default implementation, this entails storing data in the Session to indicate the successful login.
Parameters: | user – User instance |
---|
Mark the requesting user as logged-out