Google authentication using django-rest-auth and allauth

4.9k Views Asked by At

I am trying to create an authentication API for a flutter app that will log users in with a google authentication signup/login form. I followed this tutorial to achieve this.

So far so good, except that the tutorial is based on a GitHub sign in rather than Google. I managed to get it working up till step "connecting" step. I am able to get the code from the redirect but when I access http://127.0.0.1:8000/auth/google/ I see it's asking for a two fields (access_token, code). When I try to just post with the information I do have I get the following error:

 "non_field_errors": [
        "View is not defined, pass it as a context variable"
]

enter image description here

5

There are 5 best solutions below

0
On BEST ANSWER

I want to add details in the JACKSON MOURA code snippet with an explanation.

In settings.py, you have to do this. I didn't find any good documentation. But it works for social authentication. now you don't need to set up the social auth apps by using the admin panel anymore. I showed samples of Google, Facebook, and LinkedIn. It will work with other social apps as well.

SOCIALACCOUNT_PROVIDERS = {
    "google": {
        "APP": {
            "client_id": "<client_id>",
            "secret": "<secret>",
        },
    },
    'facebook': {
        "APP": {
            "client_id": "<client_id>",
            "secret": "<secret>",
        },
    },
    "linkedin": {
        "APP": {
            "client_id": "<client_id>",
            "secret": "<secret>",
        }
    }
}

Now in view.py, you have to create serializer classes. all will be the same. I am showing for Google, LinkedIn, and Facebook.

class FacebookLogin(SocialLoginView):
    adapter_class = FacebookOAuth2Adapter
    client_class = OAuth2Client
    serializer_class = SocialLoginSerializer

    def get_serializer(self, *args, **kwargs):
        serializer_class = self.get_serializer_class()
        kwargs['context'] = self.get_serializer_context()
        return serializer_class(*args, **kwargs)


class GoogleLogin(SocialLoginView):
    adapter_class = GoogleOAuth2Adapter
    client_class = OAuth2Client
    serializer_class = SocialLoginSerializer

    def get_serializer(self, *args, **kwargs):
        serializer_class = self.get_serializer_class()
        kwargs['context'] = self.get_serializer_context()
        return serializer_class(*args, **kwargs)


class LinkedInLogin(SocialLoginView):
    adapter_class = LinkedInOAuthAdapter
    client_class = OAuthClient
    serializer_class = SocialLoginSerializer

    def get_serializer(self, *args, **kwargs):
        serializer_class = self.get_serializer_class()
        kwargs['context'] = self.get_serializer_context()
        return serializer_class(*args, **kwargs)

Now, the backend is ready for getting post data from the frontend and will show perfect error like below. It will work with all other social apps.

enter image description here

0
On

I have problem with dj-rest-auth with UUID primary key and after restore default id field it start work https://github.com/iMerica/dj-rest-auth/issues/551#issuecomment-1858911936

My example of using django-allauth and dj-rest-auth

users/views.py

class GoogleLoginRedirect(RedirectView):
    url = "https://accounts.google.com/o/oauth2/v2/auth?redirect_uri=<REDIRECT_URL(WITH OUT SLASH IN THE END)>&prompt=consent&response_type=code&client_id=<CLIENT_ID>&scope=openid%20email%20profile&access_type=offline"
    permanent = True

    def get_redirect_url(self, *args, **kwargs):
        return self.url


import requests
class GoogleCallback(View):
    def get(self, request, *args, **kwargs):
        code = request.GET["code"]
        response = requests.post("http://localhost:8000/dj-rest-auth/google/", json={
            "code": code
        })

        django_response = HttpResponse(
            content=response.content,
            status=response.status_code,
        )
        for k, v in response.headers.items():
            django_response[k] = v

        return django_response

urls.py

    path('dj-rest-auth/google/', GoogleLogin.as_view(), name='google_login'),
    path("dj-rest-auth/google/login/", view=GoogleLoginRedirect.as_view(), name="google_redirect"),
    path("dj-rest-auth/google/callback/", view=GoogleCallback.as_view(), name="google_callback"),

UUID primary key not work for django-allauth = "~0.56.1" dj-rest-auth = "~5.0.2"

0
On

Try this:

class GoogleLogin(SocialLoginView):
    adapter_class = GoogleOAuth2Adapter
    client_class = OAuth2Client
    serializer_class = SocialLoginSerializer

    def get_serializer(self, *args, **kwargs):
        serializer_class = self.get_serializer_class()
        kwargs['context'] = self.get_serializer_context()
        return serializer_class(*args, **kwargs)


google_login = GoogleLogin.as_view()
0
On

It is because rest_auth is no longer maintained and is not compatible with latest versions of Django Rest Framework.

This error is resolved in switching to dj-rest-auth instead of rest_auth, which is actively maintained fork of the original project.

0
On

This is a version conflict error with djangorestframework => 3.12 Solution: Downgrade to djangorestframework <= 3.11.0 and everything should be fine.