如何解决Django社交身份验证使用自定义模型创建新用户
我正在尝试在使用自定义Django用户模型和django-rest-framework-social-oauth2作为社交身份验证软件包的应用程序上开发Facebook社交身份验证功能。我的自定义用户模型称为“帐户”,它继承自AbstractBaseUser类。帐户模型如下所示:
class Account(AbstractBaseUser):
# Account model fields:
email = models.EmailField(verbose_name='email',max_length=60,unique=True)
username = models.CharField(max_length=30,unique=True)
first_name = models.CharField(max_length=30)
last_name = models.CharField(max_length=30)
date_joined = models.DateTimeField(verbose_name='date joined',auto_now_add=True)
last_login = models.DateTimeField(verbose_name='last login',auto_now=True)
is_admin = models.BooleanField(default=False)
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
is_superuser = models.BooleanField(default=False)
# The user will log in with their email instead of username:
USERNAME_FIELD = 'email'
# Required fields when registering,other than the email:
REQUIRED_FIELDS = ['username','first_name','last_name']
# Telling the Account object how to use the account manager:
objects = MyAccountManager()
处理创建新用户的功能称为“ create_user”,并在我的自定义书面MyAccountManager类中定义,该类扩展了Django BaseUserManager类。如下所示:
class MyAccountManager(BaseUserManager):
def create_user(self,email,username,first_name,last_name,password=None):
# Checking to see if correct function parameters have been passed in:
if not email:
raise ValueError('Users must have an email address')
if not username:
raise ValueError('Users must have a username')
if not first_name:
raise ValueError('Users must have a first name')
if not last_name:
raise ValueError('Users must have a last name')
# Creating the new user:
user = self.model(
email = self.normalize_email(email),username = username,first_name = first_name,last_name = last_name,)
user.set_password(password)
user.save(using = self._db)
return user
我已经设置了有效的django-rest-framework-social-oauth2网址,用于使用Facebook帐户创建新用户。 Django settings.py文件中的相关Facebook配置如下所示:
SOCIAL_AUTH_FACEBOOK_KEY = config('SOCIAL_AUTH_FACEBOOK_KEY')
SOCIAL_AUTH_FACEBOOK_SECRET = config('SOCIAL_AUTH_FACEBOOK_SECRET')
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = { 'fields': 'id,name,email' }
我遇到的问题如下: 当使用Facebook社交登录的用户调用create_user函数时,Facebook没有提供create_user函数中必需的参数email,first_name和last_name,并且我得到了图像中所示的错误消息。该错误消息指出以下内容:
create_user()缺少2个必需的位置参数:“ first_name”和“ last_name”
有人知道我将如何从Facebook访问这些附加参数(电子邮件,名字,姓氏),以便将正确的参数传递给create_user函数?
其他信息
在实施管道建议时,我仍然遇到相同的问题,即自定义create_user函数缺少first_name和last_name参数。我认为发生这种情况的原因是由于在create_user之后调用了建议的管道cleanup_social_account函数,在本例中,first_name和last_name都是必填字段,因此,如果未在数据库中提供用户对象,则无法在数据库中创建用户对象调用create_user函数的时间。
由于建议的自定义管道中的以下功能,我收到此错误:
social_core.pipeline.user.create_user
social_core已安装库中用于此功能的代码如下:
def create_user(strategy,details,backend,user=None,*args,**kwargs):
if user:
return {'is_new': False}
fields = dict((name,kwargs.get(name,details.get(name)))
for name in backend.setting('USER_FIELDS',USER_FIELDS))
if not fields:
return
return {
'is_new': True,'user': strategy.create_user(**fields)
}
传递给上述函数的details参数包含我需要的值(first_name和last_name)。但是,创建变量时,实际上并没有将它们添加到fields变量中。字段变量显示在上方,并由以下内容定义:
fields = dict((name,USER_FIELDS))
摘要: 问题似乎是first_name和last_name没有出现在backend.settings('USER_FIELDS',USER_FIELDS)中,因此没有被添加到fields变量中,因此没有被传递到strategy.create_user(** fields) )。
解决方法
因此,当我刚刚从Facebook获得姓名和电子邮件时,social_auth会自动为我填充这些字段。它知道要输入first_name和last_name。由于它似乎不适合您,您可以创建一个自定义管道功能。
settings.py:
SOCIAL_AUTH_PIPELINE = (
'social_core.pipeline.social_auth.social_details','social_core.pipeline.social_auth.social_uid','social_core.pipeline.social_auth.auth_allowed','social_core.pipeline.social_auth.social_user','social_core.pipeline.user.get_username','social_core.pipeline.social_auth.associate_by_email','social_core.pipeline.user.create_user',# YOUR CUSTOM PIPELINE FUNCTION HERE. I CREATED A FILE/MODULE
# NAMED pipeline.py AND STUCK IT IN THERE. MAKE SURE TO PUT THIS
# AFTER CREATE USER.
'path.to.custom.pipeline.cleanup_social_account','social_core.pipeline.social_auth.associate_user','social_core.pipeline.social_auth.load_extra_data','social_core.pipeline.user.user_details',
)
pipeline.py:
def cleanup_social_account(backend,uid,user=None,*args,**kwargs):
"""
3rd party: python-social-auth.
Social auth pipeline to cleanup the user's data. Must be placed
after 'social_core.pipeline.user.create_user'.
"""
# Check if the user object exists and a new account was just created.
if user and kwargs.get('is_new',False):
*** THIS IS UNTESTED,BUT FACEBOOK'S DATA SHOULD COME INTO THE DETAILS KWARG ***
user.first_name = kwargs['details']['first_name']
user.last_name = kwargs['details']['last_name']
user.save()
return {'user': user}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。