使用django自定义用户模型的python社交认证

时间:2014-08-21 11:00:16

标签: django-rest-framework django-socialauth python-social-auth django-custom-user

我正在使用python-social-auth(不是django-social-auth,因为它被折旧)用于下面描述的Custom User Model的Django REST后端应用程序中的身份验证。

from django.contrib.auth.models import AbstractBaseUser, UserManager

class User(AbstractBaseUser):

    class Gender():
        MALE = 0
        FEMALE = 1
        UNKNOWN = 2
        CHOICES = [(MALE, 'Male'), (FEMALE, 'Female'), (UNKNOWN, 'Unknown')]

    username = models.CharField(_('username'), max_length=30, unique=True,
        help_text=_('Required. 30 characters or fewer. Letters, digits and '
                    '@/./+/-/_ only.'),
        validators=[
            validators.RegexValidator(r'^[\w.@+-]+$', _('Enter a valid username.'), 'invalid')
        ])
    first_name = models.CharField(max_length=30, blank=True)
    last_name = models.CharField(max_length=30, blank=True)
    email = models.EmailField(blank=True)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(_('active'), default=True)
    date_joined = models.DateTimeField(default=timezone.now)

    gender = models.IntegerField(choices=Gender.CHOICES, default=Gender.UNKNOWN)
    birthday = models.DateField(default=timezone.now)
    facebook_id = models.CharField(max_length=30, blank=True)

    USERNAME_FIELD = 'username'
    REQUIRED_FIELDS = ['email']
    objects = UserManager()

    def __unicode__(self):
        return self.username

    def save(self, *args, **kwargs):
        """ ensure instance has usable password when created """
        if not self.pk and self.has_usable_password() is False:
            self.set_password(self.password)

        super(User, self).save(*args, **kwargs)

请注意,我没有实现自定义UserManager。社会认证的pipline也很简单。

AUTHENTICATION_BACKENDS = (
      'social.backends.facebook.FacebookOAuth2',
      'django.contrib.auth.backends.ModelBackend',
  )

SOCIAL_AUTH_PIPELINE = (
    'social.pipeline.social_auth.social_details',
    'social.pipeline.social_auth.social_uid',
    'social.pipeline.social_auth.auth_allowed',
    'social.pipeline.social_auth.social_user',
    'social.pipeline.user.get_username',
    'social.pipeline.social_auth.associate_by_email',
    'social.pipeline.user.create_user',
    'social.pipeline.social_auth.associate_user',
    'social.pipeline.social_auth.load_extra_data',
    'social.pipeline.user.user_details'
)

但是,当我尝试使用Facebook进行身份验证时,会出现如下错误

TypeError at /api-token/login/facebook/ 'is_superuser' is an invalid keyword argument for this function

问题是,python-social-auth可能会尝试使用django自己的用户而不是我定义的自定义用户模型。 在django-social-auth中有一个设置的参数,例如SOCIAL_AUTH_USER_MODEL,但我找不到任何方法在python-social-auth

中执行此操作

如何在python-social-auth中使用我的自定义用户模型?

1 个答案:

答案 0 :(得分:0)

必须有一个自定义UserManager,如下所述。我在创建新用户时删除了is_superuser=is_superuser字段。

class UserManager(BaseUserManager):

    def _create_user(self, username, email, password,
                     is_staff, is_superuser, **extra_fields):
        """
        Creates and saves a User with the given username, email and password.
        """
        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=True, 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):
        return self._create_user(username, email, password, True, True,
                                 **extra_fields)