Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OAuth2Provider.get_scope() takes 1 positional argument but 2 were given #639

Open
shennnj opened this issue May 31, 2024 · 8 comments
Open

Comments

@shennnj
Copy link

shennnj commented May 31, 2024

Getting this error when sending a post request to SocialLoginView. The body of post request contains "code" only. Having this problem on google/facebook/github login.

Similar problem also asked in https://stackoverflow.com/questions/78477908/dj-rest-auth-with-google-login-typeerror-oauth2provider-get-scope-takes-1-po

Did I do any mistake in setting this up?

The error:
Happens during validation in SocialLoginSerializer

  File "/home/shen/.local/lib/python3.12/site-packages/rest_framework/views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/shen/.local/lib/python3.12/site-packages/dj_rest_auth/views.py", line 125, in post
    self.serializer.is_valid(raise_exception=True) <br>
  File "/home/shen/.local/lib/python3.12/site-packages/rest_framework/serializers.py", line 223, in is_valid
    self._validated_data = self.run_validation(self.initial_data)
                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 
  File "/home/shen/.local/lib/python3.12/site-packages/rest_framework/serializers.py", line 445, in run_validation
    value = self.validate(value)
            ^^^^^^^^^^^^^^^^^^^^ 
  File "/home/shen/.local/lib/python3.12/site-packages/dj_rest_auth/registration/serializers.py", line 122, in validate
    scope = provider.get_scope(request)
            ^^^^^^^^^^^^^^^^^^^^^^^^^^^

view.py

from dj_rest_auth.registration.views import SocialLoginView
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from allauth.socialaccount.providers.oauth2.client import OAuth2Client

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

    @property
    def callback_url(self):
        return f"http://localhost:3000/"

url.py

from django.urls import path, include
from . import views
from .views import GoogleLogin, google_callback
from allauth.socialaccount.providers.google import views as google_views

urlpatterns = [
    path("auth/", include("dj_rest_auth.urls")),
    path("auth/google/url/", google_views.oauth2_login, name="google_auth"), # redirect to google authentication page
    path("auth/google/callback/", google_callback, name="google_callback"), # callback from authentication page, record the authorization code
    path("auth/google/", GoogleLogin.as_view(), name="google_login"), # use authorization code to login
]

views.py

from dj_rest_auth.registration.views import SocialLoginView
from allauth.socialaccount.providers.google.views import GoogleOAuth2Adapter
from allauth.socialaccount.providers.oauth2.client import OAuth2Client

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

    @property
    def callback_url(self):
        return f"http://localhost:3000/"

from django.shortcuts import redirect
def google_callback(request):
    return redirect(f"http://localhost:3000/")

Post request
Post to /auth/google/ with body of
{ "code": "<code_received_after_user_authorize>" }

@shennnj
Copy link
Author

shennnj commented Jun 1, 2024

Seems like django-allauth update to 0.62.0 changes how get_scope is implemented, will downgrade django-allauth to 0.61.1 at the moment to have dj-rest-auth work together.

https://github.com/pennersr/django-allauth/blob/0.61.1/allauth/socialaccount/providers/oauth2/provider.py

    def get_scope(self, request):
        settings = self.get_settings()
        scope = list(settings.get("SCOPE", self.get_default_scope()))
        dynamic_scope = request.GET.get("scope", None)
        if dynamic_scope:
            scope.extend(dynamic_scope.split(","))
        return scope

https://github.com/pennersr/django-allauth/blob/0.62.0/allauth/socialaccount/providers/oauth2/provider.py

    def get_scope(self):
        """
        Returns the scope to use, taking settings `SCOPE` into consideration.
        """
        settings = self.get_settings()
        scope = list(settings.get("SCOPE", self.get_default_scope()))
        return scope

    def get_scope_from_request(self, request):
        """
        Returns the scope to use for the given request.
        """
        scope = self.get_scope()
        dynamic_scope = request.GET.get("scope", None)
        if dynamic_scope:
            scope.extend(dynamic_scope.split(","))
        return scope

@Te0SX
Copy link

Te0SX commented Jun 30, 2024

My setup with django-allauth==0.61.1 and dj-rest-auth==5.0.2 was working fine for like months. Before a few days ago I started getting errors like the above and "allauth.socialaccount.providers.oauth2.client.OAuth2Error: Invalid id_token".

Check this reply by one of the main dev of allauth: #503 (comment)

Going back to django-allauth==0.57.1 solved my issues.

@ThukuWakogi
Copy link

ThukuWakogi commented Jul 7, 2024

I came across this issue while using Github as a provider and @shennnj's solution worked for me.

However, while using dj-rest-auth 6.0.0 and django-allauth 0.63.2, I noticed that the client class in dj-rest-auth is being instantiated with an extra scope argument.

in the validate method of SocialLoginSerializer, the client is instantiated with an extra scope argument.

provider = adapter.get_provider()
scope = provider.get_scope(request)
client = self.client_class(
request,
app.client_id,
app.secret,
adapter.access_token_method,
adapter.access_token_url,
self.callback_url,
scope,
scope_delimiter=adapter.scope_delimiter,
headers=adapter.headers,
basic_auth=adapter.basic_auth,
)

This is not needed in the instantiation of a new client class

https://github.com/pennersr/django-allauth/blob/40117a711746be888528af69029cc5ed2692a7b2/allauth/socialaccount/providers/oauth2/client.py#L13-L38

So to address this problem, I inherited SocialLoginSerializer and removed the scope argument

class CstmSocialLoginSerializer(SocialLoginSerializer):
    def validate(self, attrs):
            ...
            client = self.client_class(
                request,
                app.client_id,
                app.secret,
                adapter.access_token_method,
                adapter.access_token_url,
                self.callback_url,
                scope_delimiter=adapter.scope_delimiter,
                headers=adapter.headers,
                basic_auth=adapter.basic_auth,
            )
            ...

Then added the serializer to my GithubLoginView

class GitHubLogin(SocialLoginView):
    adapter_class = GitHubOAuth2Adapter
    callback_url = "..."
    client_class = OAuth2Client
    serializer_class = CstmSocialLoginSerializer

This solved my problem and I didn't get the error.

@YDA93
Copy link

YDA93 commented Jul 14, 2024

We are encountering this issue with Apple login despite it previously functioning correctly.

@YDA93
Copy link

YDA93 commented Jul 14, 2024

We are encountering this issue with Apple login despite it previously functioning correctly.

Downgrading to django-allauth to 0.61.1 Fixes the issue.

@trackers153
Copy link

@YDA93 - could you share your dj_rest_auth version that works with django-allauth 0.61.1 for social auth via Apple?

@YDA93
Copy link

YDA93 commented Aug 28, 2024

@trackers153 Sure dj-rest-auth==6.0.0

@trackers153
Copy link

Thanks vm, @YDA93

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants