Django и react вход в систему с аутентификацией google

Я пытался настроить аутентификацию google с помощью react frontend и django rest framework backend. Я настроил и фронтенд и бэкенд, используя этот учебник из двух частей, PART1 & PART2. Когда я пытаюсь войти в систему с помощью google во фронтенде, я получаю POST http://127.0.0.1:8000/google-login/ 400 (Bad Request) Я думаю, что это потому, что мой google api требует токен доступа и код авторизации для передачи. После отладки react js я заметил, что ответ, который я получаю от google, не содержит кода авторизации. Я подозреваю, что это из-за того, что responseType по умолчанию permission, Source:React login props, вместо code. Мне интересно, как можно изменить тип ответа в react? (Я даже не уверен, что проблема только в этом)

Вот мой код бэкенда

В моем файле views.py

class GoogleLogin(SocialLoginView):
    adapter_class = GoogleOAuth2Adapter
    callback_url = "http://localhost:3000"
    client_class = OAuth2Client

в моем urls.py

path('google-login/', GoogleLogin.as_view(), name='google-login'),

для моего фронтэнда

/Components/login.js

const googleLogin = async (accesstoken,code) => {
    console.log(accesstoken)
    let res = await cacaDB.post(

      `google-login/`,
      {
        access_token: accesstoken,
        code: code 
      }
    );
    console.log(res);
    return await res.status;
};


const responseGoogle = (response) => {
    console.log(response.code);
    googleLogin(response.accessToken, response.code);

    }
return(
<div className="App">
                <h1>LOGIN WITH GOOGLE</h1>
      
                <GoogleLogin
                clientId="client_id"
                buttonText="LOGIN WITH GOOGLE"
                onSuccess={responseGoogle}
                onFailure={responseGoogle}
                />
            </div>
)

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

Этот Пост объясняет поток входа в систему за сценой. Вот Изображение потока входа Я в основном застрял на шаге возврата кода и accesstoken(я могу успешно вернуть это).

Вот мой список вопросов,

  1. How do I return code from google?
  2. I have knox token set up, can I use it instead of the JWT tokens?
  3. Does the class GoogleLogin(SocialLoginView), take care of the steps of validating the access token and code with google and creating the user with that email in database?

Буду очень признателен за ваш вклад.

После небольшого исследования с моей стороны, я думаю, что у меня может быть решение, которое подойдет вам.

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

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

Сначала, чтобы иметь чистый лист, я использовал код примера, связанный с учебниками . Я клонировал и собрал проект, и сделал следующее:

  • Создание нового проекта на GCP
    • Настроили экран согласия OAuth
      • Я установил тип пользователя "внутренний". Эта опция может быть недоступна, если вы не используете учетную запись в GSuite (как я). Хотя "External" должно быть в порядке, просто "internal" легче всего протестировать.
    • Создал клиент OAuth 2.0
      • Добавил http://localhost:3000 в разделы "Разрешенные источники JavaScript" и "Разрешенные URI перенаправления"
      • .
  • Зарегистрируйте суперпользователя Django
    • Зарегистрировал Site, со значением localhost:8000 для обоих полей.
    • Зашел в панель администратора и добавил Social Application с Client ID и Secret Key в качестве "Client ID" и "Client Secret" из GCP, соответственно. Я также выбрал сайт localhost, который мы добавили ранее, и добавил его в правое поле. ( я оставил Key пустым)

Пример страницы моего заявления

  • Заполняется поле clientId в App.js, в params компонента GoogleLogin.

Здесь я столкнулся с небольшой проблемой, но это хорошая новость, поскольку я смог воспроизвести вашу ошибку! Глядя на запрос в сетевом инспекторе, я вижу, что для меня не было передано тело, что, очевидно, является непосредственной причиной ошибки. Но если посмотреть на App#responseGoogle(response), то очевидно, что должен передаваться какой-то токен, потому что мы видим строку googleLogin(response.accessToken).

Итак, происходит то, что accounts.google.com НЕ возвращает правильный ответ, так что что-то происходит на их стороне, и мы получаем недействительный ответ, но мы молча терпим неудачу, потому что javascript есть javascript.

Изучив ответ, который выдал Google, я нашел этот связанный пост SO, который позволил мне решить проблему, и интересно, решение оказалось довольно простым: Очистить свой кэш. Честно говоря, я не совсем уверен, почему это работает, но я подозреваю, что это как-то связано с тем, что разработка ведется на вашей локальной машине (localhost/127.0.0.1 разница, возможно?).

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

У меня установлен токен knox, могу ли я использовать его вместо JWT-токенов?

Я не думаю, что у меня достаточно знаний, чтобы правильно ответить на этот вопрос, но мои предварительные исследования показывают, что нет. AFAIK, вы должны просто хранить токен, который дает вам Google, поскольку сам токен - это то, что вы будете использовать для аутентификации. Похоже, что Knox заменяет TokenAuthentication в Django, что означает, что Knox отвечает за генерацию токена. Если вы перекладываете работу по авторизации на Google, я не вижу, как вы можете использовать что-то вроде Knox. Однако я могу сильно ошибаться.

Берет ли на себя class GoogleLogin(SocialLoginView) шаги по проверке токена доступа и кода в google и созданию пользователя с этим email в базе данных?

Я так считаю. После успешной аутентификации в Google (и он правильно вызывает конечную точку бэкенда), он, похоже, создает модель "Социальный аккаунт". Пример того, что он создал для меня, приведен ниже. Он извлек всю эту информацию (например, мое имя) из Google.

Пример моей страницы "Социальные аккаунты"

Что касается того, как получить логин из локального хранилища браузера, я понятия не имею. Я не вижу никаких признаков куки, поэтому он должен хранить его где-то еще, или вам придется настроить его самостоятельно (с помощью React Providers, Services или даже Redux.

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