pythondjangodjango-rest-frameworkpython-social-auth

Is it possible to use python-social-auth's EmailAuth with drf-social-oauth2 for registration


I have a facebook authentication in my project, and I've set up some pipelines. So It would be nice for non-social email registration to also utilize these pipelines.

I tried adding EmailAuth to the authentication backends list, but I don't know what view to use now for registratioin.

So, is it possible (or reasonable) to use EmailAuth with drf-social-oauth2 for non-social registration, and if so, how do I do it?


Solution

  • You can integrate EmailAuth with drf-social-oauth2 by adding it to AUTHENTICATION_BACKENDS and using the same authentication pipelines.

    Since drf-social-oauth2 lacks a native email registration view, create a custom API endpoint that registers users manually and authenticates them via the email backend. Then, expose this view in your urls

    settings.py

    AUTHENTICATION_BACKENDS = (
        'social_core.backends.email.EmailAuth',  # The email-based autentication
        'social_core.backends.facebook.FacebookOAuth2',  # Facebook login
        'django.contrib.auth.backends.ModelBackend',  # Default auth backend
    )
    

    custom registration view

    # Other imports ..
    from rest_framework.status import HTTP_400_BAD_REQUEST, HTTP_201_CREATED
    from rest_framework.permissions import AllowAny
    from social_django.utils import load_backend, load_strategy
    from rest_framework.serializers import CharField, EmailField, Serializer
    
    class EmailRegistrationSerializer(Serializer):
        email = EmailField()
        password = CharField(max_length=100)
        member_type = CharField(max_length=20)
    
    
    class EmailRegisterView(APIView):
        permission_classes = [AllowAny]
    
        def post(self, request):
            serializer = EmailRegistrationSerializer(data=request.data)
            serializer.is_valid(raise_exception=True)
    
            strategy = load_strategy(request)
            backend = load_backend(strategy, "email", redirect_uri=None)
            user = backend.authenticate(
                response=serializer.data,
                backend=backend,
                strategy=strategy,
                request=request,
            )
            return Response({"detail": "User registered successfully"}, HTTP_201_CREATED)
    
    

    urls.py

    urlpatterns = [
        # ...
        path("auth/register/email/", EmailRegisterView.as_view(), name="email_register"),
    ]