JavaRush /Курсы /Модуль 4: FastAPI /Лекция 73: Аутентификация через OAuth2 для доступа к Goog...

Лекция 73: Аутентификация через OAuth2 для доступа к Google API

Модуль 4: FastAPI
17 уровень , 2 лекция
Открыта

Сегодня мы погрузимся в процесс аутентификации с использованием OAuth2, который является основным методом обеспечения безопасности при доступе к Google API. Изучим, как настроить FastAPI для работы с аутентификацией OAuth2, и выполним практическое взаимодействие с Google API через полученные токены доступа.

Прежде чем нырнуть в дебри кода, давайте разберёмся, зачем вообще нужен OAuth2 и как он работает.

Представьте, что вы заходите в кофейню и хотите получить доступ к её Wi-Fi. Вместо того, чтобы попросить владельца об учётных данных от маршрутизатора, вы используете QR-код для авторизации на временный доступ. OAuth2 работает примерно так же, только вместо кофе и Wi-Fi вы получаете доступ к таким "сервисам", как Google Sheets, Gmail или Google Maps.

OAuth2 — это протокол авторизации, который позволяет вашему приложению получить ограниченный доступ к ресурсам от имени пользователя. Ключевые преимущества:

  • Безопасность: мы используете токены вместо того, чтобы хранить данные логина и пароля.
  • Гибкость: можно получить разные уровни доступа (например, только чтение или полный доступ).
  • Асинхронность: отлично интегрируется в API.

Типичная "история OAuth2" состоит из следующих шагов:

  1. Пользователь заходит в ваше приложение и нажимает кнопку "Авторизоваться через Google".
  2. Ваш сервер перенаправляет пользователя на страницу авторизации Google, где он логинится и подтверждает доступ.
  3. Google возвращает вашему серверу временный код авторизации.
  4. Сервер обменивает этот код на долгоживущий токен доступа (access token).
  5. Вы используете токен для запросов к Google API.

Итак, теории хватит (хотя если не хватит, вот вам официальная документация: OAuth2 Overview)

На а теперь — к настройкам!


Настройка OAuth2 в Google Cloud Console

Чтобы воспользоваться OAuth2, нужно подготовить нашу площадку в Google Cloud Console.

Создадим учётные данные для OAuth

  1. Зайдите в Google Cloud Console.
  2. Откройте ваш проект или создайте новый.
  3. Перейдите в раздел APIs & ServicesCredentials.
  4. Нажмите Create CredentialsOAuth 2.0 Client IDs.
  5. Выберите Web application в качестве Application Type.
  6. Укажите имя клиента. Например, "FastAPI Google Auth".
  7. Добавьте в поле Authorized redirect URIs URL, куда будет возвращён пользователь после авторизации. Например:
    http://localhost:8000/auth/callback
  8. Сохраните настройки и скачайте файл с учётными данными (JSON формат).
Совет:

создайте файл client_secret.json и сохраните в корне вашего проекта. Никогда не публикуйте этот файл в открытом доступе (например, на GitHub).


Интеграция OAuth2 с FastAPI

Теперь, когда у нас есть учётные данные, пришло время интегрировать их в наше приложение на FastAPI.

Теперь установим зависимости. OAuth2 взаимодействует с Google через HTTP-запросы. Для этого нам понадобится несколько библиотек:

pip install httpx google-auth google-auth-oauthlib

Начнём с настройки базового приложения FastAPI. Создадим эндпоинты для перенаправления на Google для авторизации и получения токенов.


from fastapi import FastAPI, HTTPException
from fastapi.responses import RedirectResponse
import httpx
import os
import json
from urllib.parse import urlencode

app = FastAPI()

# Загрузка клиентских данных из файла
with open("client_secret.json", "r") as f:
    client_config = json.load(f)

CLIENT_ID = client_config["web"]["client_id"]
CLIENT_SECRET = client_config["web"]["client_secret"]
REDIRECT_URI = "http://localhost:8000/auth/callback"
AUTHORIZATION_URL = "https://accounts.google.com/o/oauth2/v2/auth"
TOKEN_URL = "https://oauth2.googleapis.com/token"
SCOPES = ["https://www.googleapis.com/auth/drive.readonly"]

user_tokens = {}  # Простая структура для хранения токенов пользователей (не используется в продакшене)

Создадим эндпоинт для авторизации.
Этот эндпоинт перенаправляет пользователя на страницу Google для получения кода авторизации:


@app.get("/auth")
def auth_request():
    # Формируем URL для авторизации
    params = {
        "client_id": CLIENT_ID,
        "response_type": "code",
        "redirect_uri": REDIRECT_URI,
        "scope": " ".join(SCOPES),
        "access_type": "offline",
        "prompt": "consent",
    }
    url = f"{AUTHORIZATION_URL}?{urlencode(params)}"
    return RedirectResponse(url)

Теперь нам нужен эндпоинт для получения токена. После успешной авторизации Google перенаправит пользователя с кодом авторизации на указанный нами URI. Обрабатываем этот код, чтобы получить токен:


@app.get("/auth/callback")
async def auth_callback(code: str):
    # Формируем запрос для обмена кода на токен
    payload = {
        "code": code,
        "client_id": CLIENT_ID,
        "client_secret": CLIENT_SECRET,
        "redirect_uri": REDIRECT_URI,
        "grant_type": "authorization_code",
    }

    async with httpx.AsyncClient() as client:
        token_response = await client.post(TOKEN_URL, data=payload)

    if token_response.status_code != 200:
        raise HTTPException(status_code=token_response.status_code, detail="Ошибка получения токена")

    # Сохраняем токен для текущего сеанса
    token_data = token_response.json()
    user_tokens["access_token"] = token_data["access_token"]
    user_tokens["refresh_token"] = token_data.get("refresh_token")

    return {"access_token": token_data["access_token"]}

Как использовать токены для запросов к API?

Поздравляю! Теперь у нас есть токены доступа. Давайте использовать их для взаимодействия с Google API. Например, мы попробуем получить список файлов на Google Диске.

Эндпоинт для доступа к Google Drive API


DRIVE_API_URL = "https://www.googleapis.com/drive/v3/files"

@app.get("/drive/files")
async def get_drive_files():
    access_token = user_tokens.get("access_token")
    if not access_token:
        raise HTTPException(status_code=401, detail="Необходима авторизация")

    # Запрос к Google Drive API
    headers = {"Authorization": f"Bearer {access_token}"}
    async with httpx.AsyncClient() as client:
        response = await client.get(DRIVE_API_URL, headers=headers)

    if response.status_code != 200:
        raise HTTPException(status_code=response.status_code, detail="Ошибка Google API")

    return response.json()

Попробуйте открыть браузер, перейти по пути /auth, успешно авторизоваться, а затем вызвать /drive/files.


Типичные ошибки и как их избежать

Работа с OAuth2 может быть немного сложной из-за множества нюансов. Вот несколько распространённых подводных камней:

  • Не забывайте обновлять токены: токены доступа обычно имеют срок действия (около часа). Используйте refresh_token для получения нового.
  • Настройки редиректа: URL, указанный в Google Cloud Console, должен точно совпадать с указанным в коде. Даже лишний / может вызвать ошибки.
  • Разграничение прав доступа: убедитесь, что ваш токен имеет соответствующие разрешения (scopes) для действий, которые вы пытаетесь выполнить.

Теперь у нас есть основа для интеграции FastAPI с Google API через OAuth2. На следующих лекциях мы будем углубляться в практическое использование Google Sheets и Drive API. Готовьтесь к ещё большему количеству кода и возможностей!

1
Задача
Модуль 4: FastAPI, 17 уровень, 2 лекция
Недоступна
Создание эндпоинта авторизации через Google OAuth2
Создание эндпоинта авторизации через Google OAuth2
1
Задача
Модуль 4: FastAPI, 17 уровень, 2 лекция
Недоступна
Получение токена доступа
Получение токена доступа
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ