Now that you've got django-browserid installed and configured, it's time to see how to customize it to your needs.
Many common customizations involve overriding methods on the
:class:`Verify <django_browserid.views.Verify>` class. But how do you use a
custom Verify
subclass?
You can substitute a custom verification view by setting :attr:`BROWSERID_VERIFY_VIEW <django.conf.settings.BROWSERID_VERIFY_VIEW>` to the import path for your view:
BROWSERID_VERIFY_VIEW = 'project.application.views.MyCustomVerifyView'
Another common way to customize django-browserid is to subclass
:class:`BrowserIDBackend <django_browserid.auth.BrowserIDBackend>`. To use a
custom BrowserIDBackend
class, simply use the python path to your custom
class in the AUTHENTICATION_BACKENDS
setting instead of the path to
BrowserIDBackend
.
After logging the user in, the default view redirects the user to :attr:`LOGIN_REDIRECT_URL <django.conf.settings.LOGIN_REDIRECT_URL>` or :attr:`LOGIN_REDIRECT_URL_FAILURE <django.conf.settings.LOGIN_REDIRECT_URL_FAILURE>`, depending on if login succeeded or failed. You can modify those settings to change where they are redirected to.
Note
You can use django.core.urlresolvers.reverse_lazy
to generate a
URL for these settings from a URL pattern name or function name.
You can also override the
:attr:`success_url <django_browserid.views.Verify.success_url` and
:attr:`failure_url <django_browserid.views.Verify.failure_url` properties on
the Verify
view if you need more control over how the redirect URLs are
retrieved.
If you need to control the entire response to the Verify
view, such as when
you're :ref:`using custom JavaScript <customjs>`, you'll want to override
:attr:`login_success <django_browserid.views.Verify.login_success`
and :attr:`login_failure <django_browserid.views.Verify.login_failure`.
If a user signs in with an email that doesn't match an existing user, django-browserid automatically creates a new User object for them that is tied to their email address. You can disable this behavior by setting :attr:`BROWSERID_CREATE_USER <django.conf.settings.BROWSERID_CREATE_USER>` to False, which will cause authentication to fail if a user signs in with an unrecognized email address.
If you want to customize how new users are created (perhaps you want to
generate a display name for them), you can override the
:attr:`create_user <django_browserid.auth.BrowserIDBackend.create_user>` method
on BrowserIDBackend
:
from django_browserid.auth import BrowserIDBackend
class CustomBackend(BrowserIDBackend):
def create_user(self, email):
username = my_custom_username_algo()
return self.User.objects.create_user(username, email)
Note
self.User
points to the User model defined in
AUTH_USER_MODEL
for custom User model support. See Custom User Models
for more details.
There are two ways to limit who can authenticate with your site: prohibiting certain email addresses, or filtering the queryset that emails are compared to.
:attr:`filter_users_by_email <django_browserid.auth.BrowserIDBackend.filter_users_by_email` returns the queryset that is searched when looking for a user account that matches a user's email. Overriding this allows you to limit the set of users that are searched:
from django_browserid.auth import BrowserIDBackend
class CustomBackend(BrowserIDBackend):
def filter_users_by_email(self, email):
# Only allow staff users to login.
return self.User.objects.filter(email=email, is_staff=True)
Note
If you customize filter_users_by_email
, you should probably make
sure that Automatic User Creation is either disabled or customized to
only create users that match your limited set.
:attr:`is_valid_email <django_browserid.auth.BrowserIDBackend.is_valid_email` determines if the email a user attempts to log in with is considered valid. Override this to exclude users with certain emails:
from django_browserid.auth import BrowserIDBackend
- class CustomBackend(BrowserIDBackend):
- def is_valid_email(self, email):
- # Ignore users from fakeemails.com return not email.endswith('@fakeemails.com')
Django allows you to use a custom User model for authentication
<custom_user_model>. If you are using a custom User model, and the model has
an email
attribute that can store email addresses, django-browserid should
work out-of-the-box for you.
If this isn't the case, then you will probably have to override the :attr:`is_valid_email <django_browserid.auth.BrowserIDBackend.is_valid_email`, :attr:`filter_users_by_email <django_browserid.auth.BrowserIDBackend.filter_users_by_email`, and :attr:`create_user <django_browserid.auth.BrowserIDBackend.create_user>` methods to work with your custom User class.
django-browserid comes with two JavaScript files to include in your webpage:
api.js
: An API for triggering logins via BrowserID and verifying assertions via the server.browserid.js
: A basic example of hooking up links with the JavaScript API.
browserid.js
only covers basic use cases. If your site has more complex
behavior behind trigger login, you should replace browserid.js
in your
templates with your own JavaScript file that uses the django-browserid
JavaScript API.
.. seealso:: :js:data:`JavaScript API <django_browserid>` API Documentation for ``api.js``.
If you want to use BrowserID for login on the built-in Django admin interface, you must use the :data:`django-browserid admin site <django_browserid.admin.site>` instead of the default Django admin site:
from django.contrib import admin
from django_browserid.admin import site as browserid_admin
from myapp.foo.models import Bar
class BarAdmin(admin.ModelAdmin):
pass
browserid_admin.register(Bar, BarAdmin)
You must also use the django-browserid admin site in your urls.py
file:
from django.conf.urls import patterns, include, url
# Autodiscover admin.py files in your project.
from django.contrib import admin
admin.autodiscover()
# copy_registry copies ModelAdmins registered with the default site, like
# the built-in Django User model.
from django_browserid.admin import site as browserid_admin
browserid_admin.copy_registry(admin.site)
urlpatterns = patterns('',
# ...
url(r'^admin/', include(browserid_admin.urls)),
)
.. seealso:: :class:`django_browserid.admin.BrowserIDAdminSite` API documentation for BrowserIDAdminSite, including how to customize the login page (such as including a normal login alongside BrowserID login).
By default, django-browserid supports use in Django templates as well as use in Jinja2 templates via the jingo library. Template helpers are registered as helper functions with jingo, so you can use them directly in Jinja2 templates:
<div class="authentication">
{% if user.is_authenticated() %}
{{ browserid_logout(text='Logout') }}
{% else %}
{{ browserid_login(text='Login', color='dark') }}
{% endif %}
</div>
{{ browserid_js() }}
For other libraries or template languages, you will have to register the django-browserid helpers manually. The relevant helper functions can be found in the :py:mod:`django_browserid.helpers` module.