Пытаюсь реализовать вход в Google на моем приложении django-restframework - Vue, но постоянно получаю redirect_uri_mismatch

Название объясняется само собой. Я перепробовал все способы, чтобы справиться с этой проблемой, но продолжал получать одну и ту же ошибку, независимо от того, что я пробовал в течение нескольких дней. Устранение неполадок было затруднено из-за того, что я не мог проверить, какая именно строка redirect_uri передается конечной точке google.

Я решил спросить здесь в надежде, что у кого-то еще была подобная проблема и он ее решил.

Vue-side:

  • использование vue3GoogleLogin main.ts:
import vue3GoogleLogin from 'vue3-google-login'

...

const clientId = import.meta.env.VITE_VUE_APP_GOOGLE_CLIENT_ID;
app.use(vue3GoogleLogin, {clientId: clientId});

SignIn.vue:


...
      <GoogleLogin :callback="callback">
        <button class="btn btn-flex flex-center btn-light btn-lg w-100 mb-5">
            <img
              alt="Logo"
              :src="getAssetPath('media/svg/brand-logos/google-icon.svg')"
              class="h-20px me-3"
            />
            Continue with Google
        </button>
      </GoogleLogin>

...

    const callback = (response) => {
    // This callback will be triggered when the user selects or login to
    // his Google account from the popup
    console.log("Handle the response", response);
    // const googleUser = decodeCredential(response.credential);
    // console.log(googleUser);
    const jwtToken = axios.post('http://127.0.0.1:8000/dj-rest-auth/google/',{
      code: response.code
    });
     console.log(jwtToken);


    }
    
    return {
      onSubmitLogin,
      login,
      submitButton,
      getAssetPath,
      callback
    };
  },
});
</script>

console.log(response.code) показывает код авторизации, который возвращает google.

Django-side:

  • использую allauth, dj-rest-auth и другие
  • .
  • Настройки Google (client_id, secret) присутствуют не в settings.py, а в DB.

url.py:

urlpatterns = [
...
    path("dj-rest-auth/google/", GoogleLogin.as_view(), name="google_login"),
...
]

views.py:


class GoogleLogin(
    SocialLoginView
):  # if you want to use Authorization Code Grant, use this
    adapter_class = GoogleOAuth2Adapter
    callback_url = "http://127.0.0.1:8000/rest-auth/google/login/callback/"
    client_class = OAuth2Client

версии пакетов:

  • dj-rest-auth==6.0.0

  • django-allauth==0.61.1 -> использование последней версии django-allauth вызывает ошибку с dj-rest-auth

    .
  • djangorestframework==3.15.2

  • djangorestframework-simplejwt==5.3.1

  • "vue3-google-login": "^2.0.26",
    
  • Я тестирую локально. Я не пробовал тестировать это с серверами и соответствующими доменами.

  • Я старался, чтобы блоки кода были краткими, опуская импорт и другие коды.

  • Насколько я понимаю, мне не нужно добавлять callback_url к urlpatterns в url.py или настраивать для этого представление?

  • Урл http://127.0.0.1:8000/rest-auth/google/login/callback/ уже зарегистрирован в облачной консоли. Я проверял это несколько раз.

  • http://127.0.0.1:8080 (vue), http://127.0.0.1:8080 (django) оба добавлены в список авторизованных источников JavaScript.

Я попытался отследить, где заканчивается url, вплоть до: backend/venv/lib/python3.10/site-packages/allauth/socialaccount/providers/oauth2/client.py

    def get_access_token(self, code, pkce_code_verifier=None):
        data = {
            "redirect_uri": self.callback_url,
            "grant_type": "authorization_code",
            "code": code,
        }
        if self.basic_auth:
            auth = requests.auth.HTTPBasicAuth(self.consumer_key, self.consumer_secret)
        else:
            auth = None
            data.update(
                {
                    "client_id": self.consumer_key,
                    "client_secret": self.consumer_secret,
                }
            )
        params = None
        self._strip_empty_keys(data)
        url = self.access_token_url
        print(data)
        if self.access_token_method == "GET":
            params = data
            data = None
        if data and pkce_code_verifier:
            data["code_verifier"] = pkce_code_verifier
        # TODO: Proper exception handling)
        resp = (
            get_adapter()
            .get_requests_session()
            .request(
                self.access_token_method,
                url,
                params=params,
                data=data,
                headers=self.headers,
                auth=auth,
            )
        )

        access_token = None
        if resp.status_code in [200, 201]:
            # Weibo sends json via 'text/plain;charset=UTF-8'
            if (
                resp.headers["content-type"].split(";")[0] == "application/json"
                or resp.text[:2] == '{"'
            ):
                access_token = resp.json()
            else:
                access_token = dict(parse_qsl(resp.text))
        if not access_token or "access_token" not in access_token:
            raise OAuth2Error("Error retrieving access token: %s" % resp.content)
        return access_token


Где я могу проверить, что redirect_uri корректно передается в качестве тела запроса к post-запросу.

Вот большинство основных моментов. Это вызвало у меня много головной боли, и я готов предоставить любые другие детали, необходимые для решения этой проблемы.

Вернуться на верх