[Python] Issue creating a django user with python-social-auth with a custom User model and...

Discussão em 'Python' iniciado por Stack, Maio 16, 2025.

  1. Stack

    Stack Membro Participativo

    Seems like this isn't a unique problem, but I'm missing something in the solution. I'm using python-social-auth and logging in with Google. All seems to be going well, until it gets to the create_user part of the pipeline. I do have a custom User model and UserManager. On my User model I do have a role property that is hooked up to some choices. When social auth kicks in and logs someone in, it does call create_user in my User manager, however it's only passing email, and no additional fields. I was attempting to hook into the pipeline and add the required role property by adding it to the details social auth dict, but that doesn't seem to have any effect. How should I go about hooking into the create user property to add fields that won't exist as far as social auth is concerned?

    User Model

    class User(AbstractBaseUser, PermissionsMixin):
    id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
    is_staff = models.BooleanField(default=False)
    is_active = models.BooleanField(default=True)
    date_joined = models.DateTimeField(default=timezone.now)
    email = models.EmailField(_("email address"), unique=True)
    first_name = models.CharField(max_length=240, blank=True)
    last_name = models.CharField(max_length=240, blank=True)
    role = models.IntegerField(choices=RoleChoices.choices)

    USERNAME_FIELD = "email"
    REQUIRED_FIELDS = []

    objects = UserManager()

    def __str__(self):
    return self.email

    @property
    def full_name(self):
    return f"{self.first_name} {self.last_name}".strip()



    And my UserManager:

    class UserManager(BaseUserManager):
    """
    Custom user model manager where email is the unique identifiers
    for authentication instead of usernames.
    """

    def create_user(self, email, password, **extra_fields):
    """
    Create and save a User with the given email and password.
    """
    if not email:
    raise ValueError(_("The Email must be set"))

    email = self.normalize_email(email)
    user = self.model(email=email, **extra_fields)

    if password is not None:
    user.set_password(password)

    user.save()
    return user

    def create_superuser(self, email, password=None, **extra_fields):
    """
    Create and save a SuperUser with the given email and password.
    """
    extra_fields.setdefault("is_staff", True)
    extra_fields.setdefault("is_superuser", True)
    extra_fields.setdefault("is_active", True)
    extra_fields.setdefault("role", 1)

    if extra_fields.get("is_staff") is not True:
    raise ValueError(_("Superuser must have is_staff=True."))
    if extra_fields.get("is_superuser") is not True:
    raise ValueError(_("Superuser must have is_superuser=True."))
    return self.create_user(email, password, **extra_fields)


    The Social auth config:

    # Social Auth Config
    AUTHENTICATION_BACKENDS = (
    'social_core.backends.google.GoogleOAuth2',
    'django.contrib.auth.backends.ModelBackend',
    )

    LOGIN_URL = 'login'
    LOGOUT_URL = 'logout'
    LOGIN_REDIRECT_URL = 'admin'
    SOCIAL_AUTH_POSTGRES_JSONFIELD = True
    SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = os.getenv('GOOGLE_CLIENT_ID')
    SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = os.getenv('GOOGLE_CLIENT_SECRET')
    SOCIAL_AUTH_USER_MODEL = 'search.User'
    SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True
    SOCIAL_AUTH_GOOGLE_OAUTH2_IGNORE_DEFAULT_SCOPE = True
    SOCIAL_AUTH_GOOGLE_OAUTH2_SCOPE = [
    'https://www.googleapis.com/auth/calendar',
    'https://www.googleapis.com/auth/calendar.readonly',
    'https://www.googleapis.com/auth/userinfo.profile',
    'profile',
    'email'
    ]

    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',
    'search.socialauth.add_role',
    'social_core.pipeline.user.create_user',
    'social_core.pipeline.social_auth.associate_user',
    'social_core.pipeline.social_auth.load_extra_data',
    'social_core.pipeline.user.user_details',
    )



    And finally the add_role function:

    from .choices import RoleChoices


    def add_role(**kwargs):
    kwargs['details']['role'] = RoleChoices.ARTIST
    return kwargs

    Continue reading...

Compartilhe esta Página