Can't login to django admin after creating a super user with a custom user model

14,819

Solution 1

The code is fine. The problem is you're using the RemoteUserBackend exclusively, instead of the default backend:

AUTHENTICATION_BACKENDS = (
    'django.contrib.auth.backends.RemoteUserBackend',
)

I've never used it myself, but from the docs it's clear that it'll only check for a REMOTE_USER header in your requests, thus making your password login attempts irrelevant.

You could add the default ModelBackend as a fallback, if you wan't to have both available:

AUTHENTICATION_BACKENDS = (
        'django.contrib.auth.backends.RemoteUserBackend',
        'django.contrib.auth.backends.ModelBackend',
)

or get rid of the RemoteUserBackend alltogether and have your app authenticate the default way.

Hope this helps.

Solution 2

Maybe you could also try to set in the create_superuser

user.is_active = True

Solution 3

Make sure you Super User is associated to one of the profiles you have created, maybe by iserting it manually intro you DB.

Take care

Share:
14,819
berserkia
Author by

berserkia

Updated on June 29, 2022

Comments

  • berserkia
    berserkia about 2 years

    I've been trying for hours to login to the django admin panel with a successfully created superuser but cannot get the right username/pw combo right.

    I want users to just use their email as their username. I've also done my best to replicate the example in the Django docs here. I've deleted migrations, sycndb, and everything works except logging in to the admin panel.

    Relevant code: From models.py:

    from django.db import models
    from django.forms import ModelForm
    from django.contrib.auth.models import BaseUserManager, AbstractBaseUser
    
    class UserManager(BaseUserManager):
        def create_user(self, email, password=None):
            """
            Creates and saves a User with the given email
            """
            if not email:
                raise ValueError('Users must have an email address')
    
            user = self.model(
                email=UserManager.normalize_email(email),
            )
            user.set_password(password)
            user.save(using=self._db)
            return user
    
        def create_superuser(self, email, password):
            """
            Creates and saves a superuser with the given email, date of
            birth and password.
            """
            user = self.create_user(email,
                password=password
            )
    
            user.is_admin = True
            user.is_staff = True
            user.is_superuser = True
            user.save(using=self._db)
            return user
    
    
    
    class User(AbstractBaseUser):
        objects = UserManager()
        date_added = models.DateField(auto_now=False, auto_now_add=True)
        email = models.EmailField(unique=True, db_index=True)
        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = []
    
        def __unicode__(self):
            return self.email
    
        is_active = models.BooleanField(default=True)
        is_admin = models.BooleanField(default=False)
    
        def get_full_name(self):
        # The user is identified by their email address
            return self.email
    
        def get_short_name(self):
        # The user is identified by their email address
            return self.email
    
        # On Python 3: def __str__(self):
        def __unicode__(self):
            return self.email
    
        def has_perm(self, perm, obj=None):
    
        # Simplest possible answer: Yes, always
            return True
    
        def has_module_perms(self, app_label):
    
        # Simplest possible answer: Yes, always
            return True
    
        def is_staff(self):
    
        # Simplest possible answer: All admins are staff
            return self.is_admin   
    

    From admin.py:

    from django.contrib import admin
    from app.models import Relationship, Event, User
    from django import forms
    from django.contrib import admin
    from django.contrib.auth.models import Group
    from django.contrib.auth.admin import UserAdmin
    from django.contrib.auth.forms import ReadOnlyPasswordHashField
    
    
    class UserCreationForm(forms.ModelForm):
        """A form for creating new users. Includes all the required
        fields, plus a repeated password."""
    
        password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
        password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
    
        class Meta:
            model = User
            fields = ('email',)
    
        def clean_password2(self):
            # Check that the two password entries match
            password1 = self.cleaned_data.get("password1")
            password2 = self.cleaned_data.get("password2")
            if password1 and password2 and password1 != password2:
                raise forms.ValidationError("Passwords don't match")
            return password2
    
        def save(self, commit=True):
            user = super(UserCreationForm, self).save(commit=False)
            user.set_password(self.cleaned_data["password1"])
            if commit:
                user.save()
            return user
    
    
    class UserChangeForm(forms.ModelForm):
        password = ReadOnlyPasswordHashField()
    
        class Meta:
            model = User
    
        def clean_password(self):
            return self.initial["password"]
    
    
    
    
    
    class UserAdmin(UserAdmin):
        # The forms to add and change user instances
        form = UserChangeForm
        add_form = UserCreationForm
    
    
        list_display = ('email', 'is_admin')
        list_filter = ('is_admin',)
        fieldsets = (
            (None, {'fields': ('email', 'password')}),
            ('Permissions', {'fields': ('is_admin',)}),
        )
    
        add_fieldsets = (
            (None, {
                'classes': ('wide',),
                'fields': ('email', 'password1', 'password2')}
            ),
        )
        search_fields = ('email',)
        ordering = ('email',)
        filter_horizontal = ()
    
    admin.site.register(User, UserAdmin)
    admin.site.unregister(Group)
    

    Relevant settings.py code:

    MIDDLEWARE_CLASSES = (
        'django.middleware.common.CommonMiddleware',
        'django.contrib.sessions.middleware.SessionMiddleware',
        'django.middleware.csrf.CsrfViewMiddleware',
        'django.contrib.auth.middleware.AuthenticationMiddleware',
        'django.contrib.messages.middleware.MessageMiddleware',
        'django.contrib.auth.middleware.RemoteUserMiddleware',
        # Uncomment the next line for simple clickjacking protection:
        # 'django.middleware.clickjacking.XFrameOptionsMiddleware',
    )
    
    ROOT_URLCONF = 'relrem.urls'
    
    # Python dotted path to the WSGI application used by Django's runserver.
    WSGI_APPLICATION = 'relrem.wsgi.application'
    
    TEMPLATE_DIRS = (
        # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
        # Always use forward slashes, even on Windows.
        # Don't forget to use absolute paths, not relative paths.
    )
    
    INSTALLED_APPS = (
        'django.contrib.auth',
        'django.contrib.contenttypes',
        'django.contrib.sessions',
        'django.contrib.sites',
        'django.contrib.messages',
        'django.contrib.staticfiles',
        'django.contrib.admin',
        'app',
        'south',
    
        # Uncomment the next line to enable admin documentation:
        # 'django.contrib.admindocs',
    )
    
    AUTH_USER_MODEL = 'app.User'
    
    AUTHENTICATION_BACKENDS = (
        'django.contrib.auth.backends.RemoteUserBackend',
    )
    

    Sample terminal output from creating a superuser and viewing it in a table:

    Email: [email protected]
    Password:
    Password (again):
    Superuser created successfully.
    
    [
    {
    "pk": 1,
    "model": "app.user",
    "fields": {
        "is_active": true,
        "last_login": "2013-09-24T02:09:44.996Z",
        "is_admin": true,
        "date_added": "2013-09-23",
        "password": "",
        "email": "[email protected]"
    }
    }
    ]
    

    I think it must be something to do with the way the password is being saved and returned, because no matter what I do I get the "Please enter the correct email and password for a staff account. Note that both fields may be case-sensitive." message. My password I set there was "sample". I've tried removing all of the code related to hashing the pw and cleaning it, but that actually still returns a hash in the user table.

    I hope I'm doing something obvious wrong, thanks in advance to anyone who takes the time to look through this whole question.

  • berserkia
    berserkia almost 11 years
    Thanks for taking the time to look it over, unfortunately still have the same problem. I deleted the AUTHENTICATION_BACKEND line and anything related to RemoteUser, and I'm still unable to login.
  • kirbuchi
    kirbuchi almost 11 years
    @berserkia did you also add 'django.contrib.auth.backends.ModelBackend' to your AUTHENTICATION_BACKENDS? Can you update your question to show your current settings.py?