#25187: Make request available in authentication backends ----------------------------------------+------------------------ Reporter: carljm | Owner: nobody Type: New feature | Status: new Component: contrib.auth | Version: 1.8 Severity: Normal | Keywords: Triage Stage: Unreviewed | Has patch: 0 Needs documentation: 0 | Needs tests: 0 Patch needs improvement: 0 | Easy pickings: 0 UI/UX: 0 | ----------------------------------------+------------------------ In some cases it is important for an authentication backend to have access to additional data from the request; for instance, the request host (if implementing host-based multi-tenancy, where each user should be restricted to login only on their assigned host/site).
Currently, it's quite difficult to do this. The two options are a) making the request thread-local, which is temptingly easy but Django otherwise has resisted, or b) replacing/copying quite large chunks of code: all of `AuthenticationForm.clean()`, `AuthenticationMiddleware`, `auth.middleware.get_user` and `auth.get_user`. My favorite option to resolve this takes advantage of the fact that authentication backends are re-instantiated for every use (by `load_backend`), and so the request could be passed into them as an instantiation argument, making it always available as `self.request`. This avoids needing to change the signatures of any methods on a backend, keeping `self.request` unobtrusive for backends which don't need it. It does mean that we'd need a deprecation path towards requiring custom backends to accept this new initialization parameter; or else we'd need a class attribute flag like `accepts_request` to explicitly mark backends which want the request. The other necessary change would be to pass the request from `AuthenticationForm` into `contrib.auth.authenticate`, so it can pass it on to the backend instantiation. We've backed ourselves into a bit of a corner here with the `**credentials` signature of `authenticate`; we can't add even an optional `request` argument without potentially breaking existing backends that pass `request` as an actual credential. One option would be a new `authenticate_with_request` function which would be used by `AuthenticationForm`, but leave the existing `authenticate` signature as- is for people who are using it directly. Very open to alternative suggestions for how to resolve the basic issue here. -- Ticket URL: <https://code.djangoproject.com/ticket/25187> Django <https://code.djangoproject.com/> The Web framework for perfectionists with deadlines. -- You received this message because you are subscribed to the Google Groups "Django updates" group. To unsubscribe from this group and stop receiving emails from it, send an email to django-updates+unsubscr...@googlegroups.com. To post to this group, send email to django-updates@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/django-updates/049.1817b6c4321322715fb6df008ef95699%40djangoproject.com. For more options, visit https://groups.google.com/d/optout.