@api_view(http_method_names=['POST'])
@permission_classes([AllowAny])
@psa()
def exchange_token(request, backend):
serializer = SocialSerializer(data=request.data)
if serializer.is_valid(raise_exception=True):
# This is the key line of code: with the @psa() decorator above,
# it engages the PSA machinery to perform whatever social authentication
# steps are configured in your SOCIAL_AUTH_PIPELINE. At the end, it either
# hands you a populated User model of whatever type you've configured in
# your project, or None.
user = request.backend.do_auth(serializer.validated_data['access_token'])
if user:
# if using some other token back-end than DRF's built-in TokenAuthentication,
# you'll need to customize this to get an appropriate token object
token, _ = Token.objects.get_or_create(user=user)
return Response({'token': token.key})
else:
return Response(
{'errors': {'token': 'Invalid token'}},
status=status.HTTP_400_BAD_REQUEST,
)
在您的设置(完整代码)中只需要添加一点内容,然后就完成了:
AUTHENTICATION_BACKENDS = (
'social_core.backends.google.GoogleOAuth2',
'social_core.backends.facebook.FacebookOAuth2',
'django.contrib.auth.backends.ModelBackend',
)
for key in ['GOOGLE_OAUTH2_KEY',
'GOOGLE_OAUTH2_SECRET',
'FACEBOOK_KEY',
'FACEBOOK_SECRET']:
# Use exec instead of eval here because we're not just trying to evaluate a dynamic value here;
# we're setting a module attribute whose name varies.
exec("SOCIAL_AUTH_{key} = os.environ.get('{key}')".format(key=key))
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',
'social_core.pipeline.social_auth.associate_by_email',
'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',
)
在您的 urls.py 中添加到此函数的映射,一切就绪!