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

Лекція 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 Drive.

Ендпоінт для доступу до 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. Готуйся до ще більшої кількості коду і можливостей!

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ