Customization

Now that you’ve got django-browserid installed and configured, it’s time to see how to customize it to your needs.

Local Assertion Verification

When a user authenticates via django-browserid, they do so by sending your site an assertion, which, when verified, gives you an email address for the user. Normally, this verification is handled by sending the assertion to a verification service hosted by Mozilla.

However, you can also verify assertions locally and avoid relying on the verification service. To do so, you must install PyBrowserID. django-browserid checks for PyBrowserID, and if it is found, it enables the use of the LocalVerifier class.

Once you’ve installed PyBrowserID, add the LocalBrowserIDBackend class to your AUTHENTICATION_BACKENDS setting:

AUTHENTICATION_BACKENDS = (
    'django_browserid.auth.LocalBrowserIDBackend',
)

Note

Because the BrowserID certificate format has not been finalized, PyBrowserID may fail to verify a valid assertion if the format changes. Be aware of the risks before enabling local verification.

Customizing the Verify View

Many common customizations involve overriding methods on the Verify class. But how do you use a custom Verify subclass?

You can substitute a custom verification view by setting BROWSERID_VERIFY_CLASS to the import path for your view:

BROWSERID_VERIFY_CLASS = 'project.application.views.MyCustomVerifyClass'

Customizing the Authentication Backend

Another common way to customize django-browserid is to subclass 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.

Post-login Response

After logging the user in, the default view redirects the user to LOGIN_REDIRECT_URL or 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 success_url and 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 using custom JavaScript, you’ll want to override login_success and login_failure.

Automatic User Creation

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 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 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.

Limiting Authentication

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.

filter_users_by_email

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.

is_valid_email

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‘)

Custom User Models

Django allows you to use a custom User model for authentication. 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 is_valid_email, filter_users_by_email, and create_user methods to work with your custom User class.

Using the JavaScript API

django-browserid comes with two JavaScript files to include in your webpage:

  1. api.js: An API for triggering logins via BrowserID and verifying assertions via the server.
  2. 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.

See also

JavaScript API
API Documentation for api.js.

Django Admin Support

If you want to use BrowserID for login on the built-in Django admin interface, you must use the 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)),
)

See also

django_browserid.admin.BrowserIDAdminSite
API documentation for BrowserIDAdminSite, including how to customize the login page (such as including a normal login alongside BrowserID login).

Alternative Template Languages

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 django_browserid.helpers module.