:mod:`repoze.who` Application Programming Interface (API)Using the
:mod:`repoze.who` without MiddlewareUsing
- At application startup, it must create an :class:`repoze.who.api:APIFactory` instance, populating it with a request classifier, a challenge decider, and a set of plugins. It can do this process imperatively (see :ref:`imperative_configuration`), or using a declarative configuration file (see :ref:`declarative_configuration`). For the latter case, there is a convenience function, :func:`repoze.who.config.make_api_factory_with_config`:
# myapp/run.py from repoze.who.config import make_api_factory_with_config who_api_factory = None def startup(global_conf): global who_api_factory who_api_factory = make_api_factory_with_config(global_conf, '/path/to/who.config')
- When it needs to use the API, it must call the
APIFactory, passing the WSGI environment to it. The
APIFactoryreturns an object implementing the :class:`repoze.who.interfaces:IRepozeWhoAPI` interface.
# myapp/views.py from myapp.run import who_api_factory def my_view(context, request): who_api = who_api_factory(request.environ)
- Calling the
APIFactorymultiple times within the same request is allowed, and should be very cheap (the API object is cached in the request environment).
:mod:`repoze.who` Middleware and APIMixed Use of
An application which uses the :mod:`repoze.who` middleware may still need
to interact directly with the
IRepozeWhoAPI object for some purposes.
In such cases, it should call :func:`repoze.who.api:get_api`, passing
the WSGI environment.
from repoze.who.api import get_api def my_view(context, request): who_api = get_api(request.environ)
Alternately, the application might configure the
APIFactory at startup,
as above, and then use it to find the API object, or create it if it was
not already created for the current request (e.g. perhaps by the middleware):
def my_view(context, request): who_api = context.who_api_factory(request.environ)
Writing a Custom Login View
:class:`repoze.who.api.API` provides a helper method to assist developers who want to control the details of the login view. The following BFG example illustrates how this API might be used:
This application is written as a "hybrid": the :mod:`repoze.who` middleware injects the API object into the WSGI enviornment on each request.
- In line 4, this application extracts the API object from the environ using :func:`repoze.who.api:get_api`.
- Lines 6 - 8 fabricate a set of credentials, based on the values the user entered in the form.
- In line 9, the application asks the API to authenticate those credentials, returning an identity and a set of respones headers.
- Lines 10 and 11 handle the case of successful authentication: in this case, the application redirects to the site root, setting the headers returned by the API object, which will "remember" the user across requests.
- Line 13 is reached on failed login. In this case, the headers returned in line 9 will be "forget" headers, clearing any existing cookies or other tokens.
- Lines 14 - 16 perform a "fake" login, in order to get the "forget" headers.
- Line 18 sets the "forget" headers to clear any authenticated user for subsequent requests.
- Lines 19 - 20 clear any authenticated user for the current request.
- Line 22 returns any message about a failed login to the rendering template.