0

I'm failing to authenticate my user upon the registration. I've found out the solution for one time link token authentication, was tampering with ModelBackend you can see the basic solution here, I'll paste up my implementation because I'm using CBV for the view.

Custom ModelBackend:

from django.contrib.auth.backends import ModelBackend
import logging

from business_accounts.models.my_user import MyUser

logger = logging.getLogger(__name__)


class UrlTokenBackend(ModelBackend):
    """
    Custom login backend that will accept token allow click url login
    """
    def authenticate(self, request, token=None):
        try:
            user = MyUser.objects.get(token=token)
        except MyUser.DoesNotExist:
            logger.warning('My user=%s does not exist', user)
            return None

        if not user.is_active:
            return None

    def get_user(self, user_id):
        try:
            return MyUser.objects.get(pk=user_id)
        except MyUser.DoesNotExist:
            logger.warning('User with this id=%s does not exists', user_id)
            return None

The authentication middleware is registered here

AUTHENTICATION_BACKENDS = (

    'business_accounts.backends.UrlTokenBackend',
    # Needed to login by username in Django admin, regardless of `allauth`
    'django.contrib.auth.backends.ModelBackend',

    # `allauth` specific authentication methods, such as login by e-mail
    'allauth.account.auth_backends.AuthenticationBackend',

)

Custom view is:

from django.contrib.auth import authenticate, login
from django.shortcuts import redirect
from django.views.generic import View


    class UrlGatewayLogin(View):
        def get(self, request):
            token = request.GET.get('token')
            user = authenticate(token=token)
            login(request, user)

            return redirect('dashboard')

and the url is

url(r'^auth/login/', UrlGatewayLogin.as_view(), name='auth-login')

Now I'll construct a url for the login, like so, http:/localhost:8000/auth/login/?token=12323344 so the whole process will just login the user over this link and redirect him to the dashboard. The login is showing me this error:

Environment:


Request Method: GET
Request URL: http://localhost:8888/auth/login/?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE1MjYzNjE5MTksInVzZXJfaWQiOjcwLCJlbWFpbCI6ImFkbWluQGFkbWluLmFpIiwidXNlcm5hbWUiOiJhZG1pbkBhZG1pbi5haSIsIm9yaWdfaWF0IjoxNTI2MzU4OTE5fQ.qyR5SYZ1uO0reVSRjcFdXGGhgfKhdu1eU277UAGU5l8

Django Version: 1.8.5
Python Version: 3.4.2
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'django.contrib.sites',
 'allauth',
 'allauth.account',
 'allauth.socialaccount',
 'allauth.socialaccount.providers.facebook',
 'allauth.socialaccount.providers.twitter',
 'allauth.socialaccount.providers.foursquare',
 'allauth.socialaccount.providers.google',
 'rest_framework',
 'rest_framework_swagger',
 'django_filters',
 'corsheaders',
 'gunicorn',
 'googleads',
 'django_nose',
 'webpack_loader',
 'common',
 'business_accounts',
 'search',
 'platforms_search',
 'locations',
 'reviews',
 'socialmedia',
 'inbox',
 'stats',
 'usermanagement',
 'connect',
 'dashboard',
 'freetrial',
 'billing',
 'demo',
 'social_tickets',
 'external',
 'test_account']
Installed Middleware:
('django.contrib.sessions.middleware.SessionMiddleware',
 'corsheaders.middleware.CorsMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.auth.middleware.SessionAuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware',
 'django.middleware.security.SecurityMiddleware',
 'django.middleware.common.CommonMiddleware')


Traceback:
File "/srv/bspotted.net/venv/lib/python3.4/site-packages/django/core/handlers/base.py" in get_response
  132.                     response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/srv/bspotted.net/venv/lib/python3.4/site-packages/django/views/generic/base.py" in view
  71.             return self.dispatch(request, *args, **kwargs)
File "/srv/bspotted.net/venv/lib/python3.4/site-packages/django/views/generic/base.py" in dispatch
  89.         return handler(request, *args, **kwargs)
File "/srv/bspotted.net/app/business_accounts/views/url_gateway_login.py" in get
  10.         login(request, user)
File "/srv/bspotted.net/venv/lib/python3.4/site-packages/django/contrib/auth/__init__.py" in login
  111.     request.session[SESSION_KEY] = user._meta.pk.value_to_string(user)
File "/srv/bspotted.net/venv/lib/python3.4/site-packages/django/utils/functional.py" in inner
  226.         return func(self._wrapped, *args)

Exception Type: AttributeError at /auth/login/
Exception Value: 'AnonymousUser' object has no attribute '_meta'

So can someone explain why is this happening and how can I overcome this, thank you.

copser
  • 2,523
  • 5
  • 38
  • 73

1 Answers1

1

authenticate() should return user object:

class UrlTokenBackend(ModelBackend):
    """
    Custom login backend that will accept token allow click url login
    """
    def authenticate(self, request, token=None):
        try:
            user = MyUser.objects.get(token=token)
        except MyUser.DoesNotExist:
            logger.warning('My user=%s does not exist', user)
            return None

        if not user.is_active:
            return None
        return user
neverwalkaloner
  • 46,181
  • 7
  • 92
  • 100