Django休息验证登录和注册失败

时间:2016-06-13 00:52:05

标签: django django-rest-framework django-rest-auth

我正在构建一个新的Djnago应用程序。我正在使用django-rest-auth(http://django-rest-auth.readthedocs.io/en/latest/index.html)进行登录和注册。但是它有一些问题。

确切的问题是:

  1. 登录时:当我尝试使用表单和原始数据选项登录API时,登录失败。它会出现"non_field_errors": ["User account is disabled."]错误。
  2. 注册:当我填写数据并进行注册时,它会给我错误,但数据会保存在数据库中。
  3. 现在我做了很多事情,我不确定我做错了什么,我按照以下顺序做了事情

    1. 创建了一个新的Django休息项目
    2. 创建了一个名为myauth的应用程序,以拥有自定义用户模型,如下所示:

      class UserManager(BaseUserManager):
      
      def _create_user(self, username, email, password, is_staff, is_superuser, **extra_fields):
      now = timezone.now()
      if not username:
       raise ValueError(_('The given username must be set'))
      email = self.normalize_email(email)
      user = self.model(username=username, email=email,
           is_staff=is_staff, is_active=False,
           is_superuser=is_superuser, last_login=now,
           date_joined=now, **extra_fields)
      user.set_password(password)
      user.save(using=self._db)
      return user
      
      def create_user(self, username, email=None, password=None, **extra_fields):
      return self._create_user(username, email, password, False, False,
               **extra_fields)
      
      def create_superuser(self, username, email, password, **extra_fields):
      user=self._create_user(username, email, password, True, True,
               **extra_fields)
      user.is_active=True
      user.save(using=self._db)
      return user
      
      
      class User(AbstractBaseUser, PermissionsMixin):
         username = models.CharField(_('username'), max_length=30, unique=True,
         help_text=_('Required. 30 characters or fewer. Letters, numbers and @/./+/-/_ characters'),
         validators=[
         validators.RegexValidator(re.compile('^[\w.@+-]+$'), _('Enter a valid username.'), _('invalid'))
         ])
         first_name = models.CharField(_('first name'), max_length=30, blank=True, null=True)
         last_name = models.CharField(_('last name'), max_length=30, blank=True, null=True)
         email = models.EmailField(_('email address'), max_length=255, unique=True)
         is_staff = models.BooleanField(_('staff status'), default=False,
         help_text=_('Designates whether the user can log into this admin site.'))
         is_active = models.BooleanField(_('active'), default=False,
         help_text=_('Designates whether this user should be treated as active. Unselect this instead of deleting accounts.'))
         date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
         receive_newsletter = models.BooleanField(_('receive newsletter'), default=False)
         birth_date = models.DateField(auto_now=False, null=True)
         address = models.TextField(max_length=500, null=True)
         phone_regex = RegexValidator(regex=r'^\+?1?\d{9,15}$', message="Phone number must be entered in the format: '+999999999'. Up to 15 digits allowed.")
         phone_number = models.CharField(validators=[phone_regex], blank=True, max_length=20) # validators should be a list
      
      
        USERNAME_FIELD = 'email'
        REQUIRED_FIELDS = ['username',]
      
        objects = UserManager()
      
        class Meta:
         verbose_name = _('user')
         verbose_name_plural = _('users')
      
        def get_full_name(self):
          full_name = '%s %s' % (self.first_name, self.last_name)
          return full_name.strip()
      
       def get_short_name(self):
          return self.first_name
      
      def email_user(self, subject, message, from_email=None):
          send_mail(subject, message, from_email, [self.email]) 
      
    3. 在settings.py中将其添加为AUTH_USER_MODEL = 'myauth.User',并在admin.py中注册。迁移使用上面提到的列创建了所有表。

    4. 我想修改注册,以便能够注册first_name和last_name以及用户名,电子邮件和密码。也可以使用电子邮件而不是用户名登录。因此,我的用户模型和settings.py中可能存在冲突代码。在我的serializers.py中,我添加了以下代码:

       from myauth.models import User
      
       from allauth.account import app_settings as allauth_settings
       from allauth.utils import email_address_exists
       from allauth.account.adapter import get_adapter
       from allauth.account.utils import setup_user_email
      
       #Custom registration to store first and last name along with email and password 
       class RegisterSerializer(serializers.Serializer):
       email = serializers.EmailField(required=allauth_settings.EMAIL_REQUIRED)
       first_name = serializers.CharField(required=True, write_only=True)
       last_name = serializers.CharField(required=True, write_only=True)
       password1 = serializers.CharField(required=True, write_only=True)
       password2 = serializers.CharField(required=True, write_only=True)
      
       def validate_email(self, email):
           email = get_adapter().clean_email(email)
           if allauth_settings.UNIQUE_EMAIL:
             if email and email_address_exists(email):
              raise serializers.ValidationError(
                  _("A user is already registered with this e-mail address."))
       return email
      
       def validate_password1(self, password):
         return get_adapter().clean_password(password)
      
       def validate(self, data):
         if data['password1'] != data['password2']:
          raise serializers.ValidationError(
              _("The two password fields didn't match."))
        return data
      
       def get_cleaned_data(self):
         return {
          'first_name': self.validated_data.get('first_name', ''),
          'last_name': self.validated_data.get('last_name', ''),
          'password1': self.validated_data.get('password1', ''),
          'email': self.validated_data.get('email', ''),
        }
      
       def save(self, request):
         adapter = get_adapter()
         user = adapter.new_user(request)
         self.cleaned_data = self.get_cleaned_data()
         adapter.save_user(request, user, self)
         setup_user_email(request, user, [])
         user.save()
         return user
      
    5. 我的settings.py如下所示:

      INSTALLED_APPS = (
       'django.contrib.admin',
       'django.contrib.auth',
       'django.contrib.contenttypes',
       'django.contrib.sessions',
       'django.contrib.messages',
       'django.contrib.staticfiles',
       'rest_framework',
       'rest_framework.authtoken',
       'rest_auth',
       'allauth',
       'allauth.account',
       'rest_auth.registration',
       'myauth',
       'swarms_app'
      )
      
      AUTH_USER_MODEL = 'myauth.User'
      
      MIDDLEWARE_CLASSES = (
       'django.contrib.sessions.middleware.SessionMiddleware',
       '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',
       )
      
       ROOT_URLCONF = 'urls'
      
      TEMPLATES = [
      {
          'BACKEND': 'django.template.backends.django.DjangoTemplates',
          'DIRS': [],
          'APP_DIRS': True,
          'OPTIONS': {
              'context_processors': [
                  'django.template.context_processors.debug',
                  'django.template.context_processors.request',
                  'django.contrib.auth.context_processors.auth',
                  'django.contrib.messages.context_processors.messages',
              ],
            },
          },
         ]
      
         WSGI_APPLICATION = 'config.wsgi.application' 
      
      DATABASES = {
      'default': {
          'ENGINE': 'django.db.backends.mysql',  
          'NAME': 'new_swarms',
          'USER': 'root',
          'PASSWORD': 'root',
          'HOST': 'localhost',   # Or an IP Address that your DB is hosted on
          'PORT': '3306',
      }
      }
      
      
      STATIC_URL = '/static/'
      
      ##############################################################
      ## All the customization as taken from original swarms code ## 
      ##############################################################
      
      
      #This is added to use custon registration serializer which stores first and last name along with email and password
      REST_AUTH_REGISTER_SERIALIZERS = {
          'REGISTER_SERIALIZER': 'myauth.serializers.RegisterSerializer',
      } 
      
      REST_FRAMEWORK = {
      'DEFAULT_AUTHENTICATION_CLASSES': (
          'rest_framework.authentication.BasicAuthentication',
          'rest_framework.authentication.SessionAuthentication',
          'rest_framework.authentication.TokenAuthentication',
      )
      }
      
      #Following is added to enable registration with email instead of username
      AUTHENTICATION_BACKENDS = (
      # 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",
      )
      
      #This is required otherwise it asks for email server
      EMAIL_BACKEND = 'django.core.mail.backends.console.EmailBackend'
      
      ACCOUNT_AUTHENTICATION_METHOD = 'email'
      ACCOUNT_EMAIL_REQUIRED = True   
      ACCOUNT_USERNAME_REQUIRED = False
      
    6. 我创建的自定义模型似乎有效,因为在迁移时它创建了包含所有提到的字段的表。我甚至可以在我的管理界面中看到它。

      这里出了什么问题?

2 个答案:

答案 0 :(得分:1)

user = self.model(username=username, email=email,
     is_staff=is_staff, is_active=False,
     is_superuser=is_superuser, last_login=now,
     date_joined=now, **extra_fields)

您已将此(is_active)设置为默认值“false”。我认为注册它会禁用用户。这就是原因,登录时你会得到“禁用”的响应。

请在注册或创建新帐户时使is_active = true。

答案 1 :(得分:1)

当注册和登录开始工作时,我确实升级了Django版本并重新安装了django-rest-auth和django-allauth,但不完全正确。

通过API,只有在使用原始数据时才有可能,而不是在使用HTML表单时,请参阅屏幕截图:

enter image description here

退出 仍然存在。

enter image description here

这两个问题的任何进一步答案? 注销通过HTML启用