如何解决Python-Social-Auth:无法保存来自 Linkedin 的电子邮件地址值以用于管道
我已按照此文档中的说明进行操作:https://readthedocs.org/projects/python-social-auth/downloads/pdf/latest/(第 121 页)以及类似查询中的说明:python-social-auth partial pipeline can not resume 但我无法从数据库中获取电子邮件地址值,即在我的管道中,我不确定如何从下面的行中获取 kwargs['email'] 上的值。 user = User.objects.get(email=kwargs['email'])
有哪位大神能帮帮我吗?非常感谢!
设置如下:
forms.py
class SocialPasswordForm(forms.Form):
password = forms.CharField(max_length=32)
views.py
def get_user_password(request):
print('def post view first')
if request.method == 'POST':
print('def post view second')
form = SocialPasswordForm(request.POST)
if form.is_valid():
print('def post view third')
# because of FIELDS_STORED_IN_SESSION,this will get copied
# to the request dictionary when the pipeline is resumed
request.session['local_password'] = form.cleaned_data.get('password')
#backend = request.session['partial_pipeline']['backend']
# once we have the password stashed in the session,we can
# tell the pipeline to resume by using the "complete" endpoint
print('def post view fourth')
return redirect(reverse('social:complete',args=('linkedin-oauth2',)))
else:
form = SocialPasswordForm()
return render(request,'social_signup.html',{'form': form})
auth_pipeline.py
from django.shortcuts import redirect
from django.contrib.auth import get_user_model
User = get_user_model()
from social_core.pipeline.partial import partial
# partial says "we may interrupt,but we will come back here again"
@partial
def collect_password(strategy,backend,request,details,*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)
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=kwargs['email'])
user.set_password(local_password)
user.save()
# continue the pipeline
return
settings.py
SOCIAL_AUTH_PIPELINE = (
# Get the information we can about the user and return it in a simple
# format to create the user instance later. In some cases the details are
# already part of the auth response from the provider,but sometimes this
# Could hit a provider API.
'social_core.pipeline.social_auth.social_details',# Get the social uid from whichever service we're authing thru. The uid is
# the unique identifier of the given user in the provider.
'social_core.pipeline.social_auth.social_uid',# Verifies that the current auth process is valid within the current
# project,this is where emails and domains whitelists are applied (if
# defined).
'social_core.pipeline.social_auth.auth_allowed',# Checks if the current social-account is already associated in the site.
'social_core.pipeline.social_auth.social_user',# Make up a username for this person,appends a random string at the end if
# there's any collision.
'social_core.pipeline.user.get_username',# Send a validation email to the user to verify its email address.
# disabled by default.
#'social_core.pipeline.mail.mail_validation',# Associates the current social details with another user account with
# a similar email address. disabled by default.
'social_core.pipeline.social_auth.associate_by_email',# Create a user account if we haven't found one yet.
'social_core.pipeline.user.create_user',# Create the record that associates the social account with the user.
'social_core.pipeline.social_auth.associate_user',# Populate the extra_data field in the social record with the values
# specified by settings (and the default ones like access_token,etc).
'social_core.pipeline.social_auth.load_extra_data',# Update the user record with any changed info from the auth service.
'social_core.pipeline.user.user_details',#CUSTOM PIPELINE
'users.auth_pipeline.collect_password',)
...
SOCIAL_AUTH_FIELDS_STORED_IN_SESSION = ['local_password',]
social_signup.html
{% extends 'base.html' %}
{% load crispy_forms_tags %}
{% block title %}Home{% endblock title %}
{% block content %}
<form method="POST" class="padding">
{% csrf_token %}
{{form|crispy}}
<button type="submit">Save Password</button>
</form>
{% endblock content %}
这是错误(很明显我没有存储来自linkedin的电子邮件地址)。我如何存储它?
File "C:\...\auth_pipeline.py",line 24,in collect_password
print(kwargs['email'])
KeyError: 'email'
提前致谢。我很感激你的时间。
解决方法
将我的自定义管道更改为以下解决了该问题。
@partial
def collect_password(strategy,backend,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)
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(SocialSignUpView)
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.set_password(local_password)
user.save()
# continue the pipeline
return
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。