3

I' m trying to add a new authentication backend to my project with the following versions and code snippets:

django: 2.2.1 python: 3.5.2 mysql-server: 5.7

settings.py

...
AUTHENTICATION_BACKENDS = ['common.backends.MyOwnAuthenticationBackend']

common/backends.py

from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.contrib.auth.models import User


class MyOwnAuthenticationBackend(ModelBackend):
    print('MOAB')
    def authenticate(self, username=None, password=None):
        print('AUTH')
        ...

    def get_user(self, username):
        print('GETUSER')
        try:
            return User.objects.get(pk=username)
        except User.DoesNotExist:
            return None

While trying to log in, i get back the MOAB, but none of the AUTH or GETUSER strings.

What can be the reason for it?

The main urls.py contains the following for authentication:

urls.py

from common import views as common_views
from django.conf.urls import include, url
from django.contrib import admin
from django.contrib.auth import views
from django.urls import path

...

url(r'^accounts/login/$', views.LoginView, name='auth_login'),

...

What did i miss? I read many questions and posts about it on the Internet, but i can' t figure out why the authenticate() method is not called at all.

3
  • Good guess. Thanks. It seems i was looking some older documentation, not for my current django version. Commented Jul 23, 2019 at 17:38
  • I don' t know what did i do. Maybe i deleted the answer from someone? Someone wrote to use request in the authenticate, like (def authenticate(self, request, username=None, password=None): which solved my problem. Sorry if it was me who deleted... . Commented Jul 23, 2019 at 17:40
  • :) no it's my bad, i said that before checking in different versions so i deleted the comment. glad it works now Commented Jul 23, 2019 at 17:42

1 Answer 1

2

The method should look like :

def authenticate(self, request, username=None, password=None):

You can can check the parameters needed for the signature of the method authenticate by looking at the source of authentication system. The first positioned parameter is request, and then the credentials are unpacked as named parameters:

def authenticate(request=None, **credentials):
    """
    If the given credentials are valid, return a User object.
    """
    for backend, backend_path in _get_backends(return_tuples=True):
        try:
            inspect.getcallargs(backend.authenticate, request, **credentials)
        except TypeError:
            # This backend doesn't accept these credentials as arguments. Try the next one.
            continue
        try:
            user = backend.authenticate(request, **credentials)
     [...]

(_get_backends represents the list of all backends in settings.AUTHENTICATION_BACKENDS)

Doc about custom authentication :
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#writing-an-authentication-backend

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.