python-social-auth: 新注册用户设置密码后无法保持登录状态

python-social-auth: Unable to keep logged in newly registered user after setting password

我确定问题源于此语句:user.set_password(local_password) 因为当我省略它时,管道以用户按预期登录结束。

现在,正如其他人指出的那样,在使用 set_password 方法后,django 会自动结束会话,以避免我们可能使用 update_session_auth_hash (request, user)。问题是这在管道中不起作用。我也尝试添加:

        user = authenticate(username=user, password=local_password)
        login(request, user)

这也不行。

我还通过打印语句检查了用户是否已通过身份验证,它恰好在我检查的所有 3 个步骤中。

最后,我还尝试创建一个新的管道方法并在之后调用它。这个也没用。

@partial
def login_users(strategy, request, user, *args, **kwargs):
    user = authenticate(username=user, password=strategy.session_get('local_password', None))
    print(user.is_authenticated)
    request = strategy.request
    login(request, user)
    messages.success(request, "Welcome, you have successfully signed up")
    return

总而言之,为了避免这里的数据溢出,一切都按预期工作,但是一旦我通过 user.set_password(local_password) 保存密码,用户就会注销并需要再次单击 Linkedin 以登录。否则,行为将如预期的那样,即保存收集的数据并在管道末尾显示主页。 请在下面查看我的管道。

@partial
def collect_password(strategy, request, details, is_new=False, *args, **kwargs):
    # session 'local_password' is set by the pipeline infrastructure
    # because it exists in FIELDS_STORED_IN_SESSION
    local_password = strategy.session_get('local_password', None)
    local_country = strategy.session_get('local_country', None)       
    if is_new:
        if not local_password:
            # if we return something besides a dict or None, then that is
            # returned to the user -- in this case we will redirect to a
            # view that can be used to get a password
            return redirect('social_signup')
            # grab the user object from the database (remember that they may
            # not be logged in yet) and set their password. (Assumes that the
            # email address was captured in an earlier step.)
        user = User.objects.get(email=details['email'])
        user.country = local_country
        user.set_password(local_password)
        user.save()
        update_session_auth_hash (request, user)
        print(user.is_authenticated)
        user = authenticate(username=user, password=local_password)
        login(request, user)
        print(user.is_authenticated)
    return 

如果你碰巧知道这个,我欠你一杯咖啡 :D。 非常感谢。

部分流水线是身份验证过程中的一站。扩展后端并覆盖 get_user_details 方法后,此密码设置代码可能会更好。

也就是说,部分管道用于在实际身份验证发生之前做一些工作。不需要调用 authenticatereturn,social-auth 将在部分代码完成后执行此操作。

此外,当前用户实例可以作为参数访问。

@partial
def collect_password(strategy, backend, request, details, user=None, is_new=False, *args, **kwargs):
    # session 'local_password' is set by the pipeline infrastructure
    # because it exists in FIELDS_STORED_IN_SESSION
    local_password = strategy.session_get('local_password', None)
    local_country = strategy.session_get('local_country', None)

    if is_new:
        if not local_password:
            return strategy.redirect('social_signup') # changed redirect to use p-s-a methods

        if user: # user is a parameter to the pipeline methods
            user.country = local_country
            user.set_password(local_password)
            user.save()