社交登录drf django

时间:2020-01-10 16:54:08

标签: django python-3.x django-rest-framework

我正在尝试通过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)

views.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', )

用户模型.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

1 个答案:

答案 0 :(得分:0)

在settings.py内,您必须将Facebook添加为服务提供商

您必须添加

AUTHENTICATION_BACKENDS = [
# Others auth providers (e.g. Google, OpenId, etc)
# Facebook OAuth2
'social_core.backends.facebook.FacebookAppOAuth2',
'social_core.backends.facebook.FacebookOAuth2',
# django-rest-framework-social-oauth2
'rest_framework_social_oauth2.backends.DjangoOAuth2',
# Django
'django.contrib.auth.backends.ModelBackend',
]