Я пытаюсь реализовать социальный вход с помощью Facebook и Google. Я использую Django -rest-framework-social-oauth2
serializers.py:
class SocialSerializer(serializers.Serializer):
provider = serializers.CharField(max_length=255, required=True)
access_token = serializers.CharField(max_length=4096, required=True, trim_whitespace=True)
просмотров .py:
class SocialLoginView(generics.GenericAPIView):
serializer_class = serializers.SocialSerializer
permission_classes = [permissions.AllowAny]
def post(self, request):
"""Authenticate user through the provider and access_token"""
serializer = self.serializer_class(data=request.data)
serializer.is_valid(raise_exception=True)
provider = serializer.data.get('provider', None)
strategy = load_strategy(request)
try:
backend = load_backend(strategy=strategy, name=provider,
redirect_uri=None)
except MissingBackend:
return Response({'error': 'Please provide a valid provider'},
status=status.HTTP_400_BAD_REQUEST)
try:
if isinstance(backend, BaseOAuth2):
access_token = serializer.data.get('access_token')
user = backend.do_auth(access_token)
except HTTPError as error:
return Response({
"error": {
"access_token": "Invalid token",
"details": str(error)
}
}, status=status.HTTP_400_BAD_REQUEST)
except AuthTokenError as error:
return Response({
"error": "Invalid credentials",
"details": str(error)
}, status=status.HTTP_400_BAD_REQUEST)
try:
authenticated_user = backend.do_auth(access_token, user=user)
except HTTPError as error:
return Response({
"error":"invalid token",
"details": str(error)
}, status=status.HTTP_400_BAD_REQUEST)
except AuthForbidden as error:
return Response({
"error":"invalid token",
"details": str(error)
}, status=status.HTTP_400_BAD_REQUEST)
if authenticated_user and authenticated_user.is_active:
#generate JWT token
login(request, authenticated_user)
data={
"token": jwt_encode_handler(
jwt_payload_handler(user)
)}
#customize the response to your needs
response = {
"email": authenticated_user.email,
"username": authenticated_user.username,
"token": data.get('token')
}
return Response(status=status.HTTP_200_OK, data=response)
urls.py:
path('auth/oauth/login/', views.SocialLoginView.as_view())
settings.py:
SOCIAL_AUTH_FACEBOOK_KEY = key
SOCIAL_AUTH_FACEBOOK_SECRET = 'secret'
SOCIAL_AUTH_FACEBOOK_SCOPE = ['email']
SOCIAL_AUTH_FACEBOOK_PROFILE_EXTRA_PARAMS = {
'fields': 'id, name, email'
}
FACEBOOK_EXTENDED_PERMISSIONS = ['email']
SOCIAL_AUTH_ADMIN_USER_SEARCH_FIELDS = ['username', 'first_name', 'email']
SOCIAL_AUTH_USERNAME_IS_FULL_EMAIL = True
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = 'key'
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = 'secret'
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', )
user models.py:
class UserManager(BaseUserManager):
def _create_user(self, email, password, is_staff, is_superuser, **extra_fields):
if not email:
raise ValueError('user must have email address')
now = timezone.now()
email = self.normalize_email(email)
user = self.model(
email=email,
is_staff=is_staff,
is_active=True,
is_superuser=is_superuser,
last_login=now,
date_joined=now,
**extra_fields
)
if password:
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, password=None, **extra_fields):
return self._create_user(email, password, False, False, **extra_fields)
def create_superuser(self, email, password, **extra_fields):
user=self._create_user(email, password, True, True, **extra_fields)
user.save(using=self._db)
return user
class CustomUser(AbstractBaseUser, PermissionsMixin):
USER_TYPE_CHOICES = (
('freelance_photographer', 'freelance_photographer'),
('photographer', 'photographer'),
('client', 'client'),
)
user_type = models.CharField(choices=USER_TYPE_CHOICES, null=True,max_length=20)
email = models.EmailField(max_length = 100, unique = True)
first_name = models.CharField(max_length = 100, null = True, blank = True)
last_name = models.CharField(max_length = 100, null = True, blank = True)
is_staff = models.BooleanField(default = False)
is_superuser = models.BooleanField(default = False)
is_active = models.BooleanField(default = True)
last_login = models.DateTimeField(null = True, blank = True)
date_joined = models.DateTimeField(auto_now_add=True)
USERNAME_FIELD = "email"
EMAIL_FIELD = "email"
REQUIRED_FIELD = []
objects = UserManager()
def get_absolute_url(self):
return "/users/%i/" % (self.pk)
когда я делаю почтовый запрос от почтальона с провайдером и access_token, я получаю эту ошибку:
File "/home/tboss/Desktop/environment/live/backend/liveimage/users/models.py", line 30, in create_user
return self._create_user(email, password, False, False, **extra_fields)
File "/home/tboss/Desktop/environment/live/backend/liveimage/users/models.py", line 13, in _create_user
raise ValueError('user must have email address')
ValueError: user must have email address
она получает ошибку от usermanager, но она должна получать электронную почту от facebook, и я тоже не получаю не понимаю, как пользователь собирается предоставить пользователю access_token