Call Django's authenticate function with the request object by jgeerds · Pull Request #5295 · encode/django-rest-framework (original) (raw)
Django 1.8.x, 1.9.x and 1.10.x releases use the following function signature:
def authenticate(**credentials):
This implies that it is not possible to use positional keyword arguments with this function:
In [7]: def authenticate(**credentials):
...: print(credentials)
...:
In [8]: authenticate('foo', 'bar')
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-8-b0a7d48cf507> in <module>()
----> 1 authenticate('foo', 'bar')
TypeError: authenticate() takes 0 positional arguments but 2 were given
In [9]: authenticate(username='foo', password='bar')
{'password': 'bar', 'username': 'foo'}
In [10]:
I think this is also the reason why Django 1.11 introduced request as a keyword argument as well (at least until 2.1 comes out). Passing an extra request parameter works fine with pre-1.11:
In [12]: def authenticate(**credentials):
...: print(credentials)
...:
In [13]: authenticate(request='req', username='foo', password='bar')
{'request': 'req', 'password': 'bar', 'username': 'foo'}
However, from a custom auth backend perspective I think it might fail because of this:
for backend, backend_path in _get_backends(return_tuples=True):
try:
inspect.getcallargs(backend.authenticate, **credentials)
except TypeError:
# This backend doesn't accept these credentials as arguments. Try the next one.
continue
I'll create a wrapper function in compat.py to handle old versions