Сьогодні поринемо в процес автентифікації з використанням OAuth2, який є основним методом забезпечення безпеки при доступі до Google API. Розберемося, як налаштувати FastAPI для роботи з OAuth2, і виконаємо практичну взаємодію з Google API через отримані токени доступу.
Перш ніж занурюватись у код, давай розберемося, навіщо взагалі потрібен OAuth2 і як він працює.
Уяви, що заходиш у кав'ярню і хочеш підключитись до її Wi‑Fi. Замість того, щоб просити в господаря дані від роутера, ти використовуєш QR‑код для авторизації на тимчасовий доступ. OAuth2 працює приблизно так само, тільки замість кави і Wi‑Fi ти отримуєш доступ до таких "сервісів", як Google Sheets, Gmail або Google Maps.
OAuth2 — це протокол авторизації, який дозволяє твоєму застосунку отримати обмежений доступ до ресурсів від імені користувача. Ключові переваги:
- Безпека: ми використовуємо токени замість того, щоб зберігати логін і пароль.
- Гнучкість: можна отримати різні рівні доступу (наприклад, лише читання або повний доступ).
- Асинхронність: відмінно інтегрується в API.
Типова "історія OAuth2" складається з таких кроків:
- Користувач заходить у твій застосунок і натискає кнопку "Авторизуватися через Google".
- Твій сервер перенаправляє користувача на сторінку авторизації Google, де він логіниться і підтверджує доступ.
- Google повертає твоєму серверу тимчасовий код авторизації.
- Сервер міняє цей код на довгоживучий токен доступу (access token).
- Ти використовуєш токен для запитів до Google API.
Ітак, теорії вистачить (хоча якщо не вистачить, ось офіційна документація: OAuth2 Overview)
А тепер — до налаштувань!
Налаштування OAuth2 у Google Cloud Console
Щоб користуватись OAuth2, потрібно підготувати нашу площадку в Google Cloud Console.
Створимо облікові дані для OAuth
- Зайди в Google Cloud Console.
- Відкрий свій проект або створи новий.
- Перейдіть у розділ APIs & Services → Credentials.
- Натисни Create Credentials → OAuth 2.0 Client IDs.
- Вибери Web application як Application Type.
- Вкажи ім'я клієнта. Наприклад, "FastAPI Google Auth".
- Додай у поле Authorized redirect URIs URL, куди буде повернений користувач після авторизації. Наприклад:
http://localhost:8000/auth/callback - Збережи налаштування і завантаж файл з обліковими даними (формат 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. Готуйся до ще більшої кількості коду і можливостей!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ