问题描述
我确定问题源自以下语句: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,details,is_new=False,**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,user)
print(user.is_authenticated)
return
如果你碰巧知道这个,我欠你一杯咖啡:D。 非常感谢。
解决方法
部分管道是身份验证过程中的一个停靠点。如果扩展后端并覆盖 get_user_details
方法,此密码设置代码可能会更好。
也就是说,部分管道用于在实际身份验证发生之前做一些工作。不需要调用 authenticate
和 return
,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()