Python-Social-Auth:无法从 Linkedin 保存电子邮件地址值以在管道中使用
Python-Social-Auth: Unable to save email address value from Linkedin for use in pipeline
我已按照此文档中的说明进行操作:https://readthedocs.org/projects/python-social-auth/downloads/pdf/latest/ (page 121) and also from a similar inquiry: python-social-auth partial pipeline can not resume
但我无法从数据库中获取电子邮件地址值,即在我的管道中我不太确定如何从下面的行中获取 kwargs['email'] 上的值。
用户 = 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
我已按照此文档中的说明进行操作:https://readthedocs.org/projects/python-social-auth/downloads/pdf/latest/ (page 121) and also from a similar inquiry: python-social-auth partial pipeline can not resume 但我无法从数据库中获取电子邮件地址值,即在我的管道中我不太确定如何从下面的行中获取 kwargs['email'] 上的值。 用户 = 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