пʼятниця, 9 травня 2025 р.

Як правильно виконати редірект після Google OAuth 2.0 у Flask (PythonAnywhere)

✅ Як правильно виконати редірект після Google OAuth 2.0 у Flask (PythonAnywhere)

Цей допис — нагадування самому собі, як реалізувати повернення користувача на потрібну сторінку після авторизації через Google OAuth 2.0, та як уникати помилок, які забирають півдня.

📦 Залежності

  • flask
  • authlib
  • python-dotenv
  • werkzeug.middleware.proxy_fix.ProxyFix

1. Правильна реєстрація Google OAuth


google = oauth.register(
    name='google',
    client_id=GOOGLE_CLIENT_ID,
    client_secret=GOOGLE_CLIENT_SECRET,
    server_metadata_url='https://accounts.google.com/.well-known/openid-configuration',
    api_base_url='https://openidconnect.googleapis.com/v1/',
    client_kwargs={'scope': 'openid email profile'}
)

⚠️ Без server_metadata_url буде помилка: Missing "jwks_uri" in metadata
⚠️ Без api_base_url буде помилка: Invalid URL 'userinfo'

2. Установка змінних середовища (.env)


GOOGLE_CLIENT_ID=...
GOOGLE_CLIENT_SECRET=...
SECRET_KEY=...

У WSGI-файлі обов’язково:


from dotenv import load_dotenv
load_dotenv('/home/your_user/myauth/.env')

3. Налаштування Flask


from flask import Flask
from werkzeug.middleware.proxy_fix import ProxyFix

app = Flask(__name__)
app.wsgi_app = ProxyFix(app.wsgi_app, x_proto=1, x_host=1)
app.config.update(
    SESSION_COOKIE_SECURE=True,
    SESSION_COOKIE_SAMESITE="None",
    PREFERRED_URL_SCHEME="https",
    SECRET_KEY=os.getenv("SECRET_KEY")
)

4. Обробка авторизації та редіректу


@app.route('/login')
def login():
    redirect_uri = url_for('authorize_route', _external=True)
    return google.authorize_redirect(redirect_uri)

@app.route('/authorize')
def authorize_route():
    try:
        token = google.authorize_access_token()
        userinfo_response = google.get('userinfo')
        userinfo_response.raise_for_status()
        user = userinfo_response.json()
        session['user'] = user
        return redirect(url_for('index'))
    except Exception as e:
        print("❌ Помилка під час авторизації:", e)
        return "Внутрішня помилка сервера", 500

5. Типові помилки й способи вирішення

❌ Помилка ✅ Рішення
Missing "jwks_uri" in metadata Додай server_metadata_url при реєстрації OAuth
Invalid URL 'userinfo': No scheme supplied Додай api_base_url з базовим URL
BuildError: Could not build url for endpoint 'authorize' Використовуй правильну назву функції (наприклад, authorize_route) у url_for()
TemplateNotFound: index.html Створи папку templates/ у тій самій директорії, де й main.py
Internal Server Error після login Додай логування в /authorize, перевір SECRET_KEY та сесію

🔚 Після авторизації

Функція повинна зробити редірект на:

  • url_for('index') — головна сторінка
  • Або будь-яку іншу: redirect(url_for('dashboard'))

📌 Поради

  • Ніколи не використовуй ~ у шляху до `.env` у WSGI — краще os.path.join
  • Завжди додавай ProxyFix у Flask + HTTPS
  • Перевір ідеальну відповідність redirect URI в Google Console
  • Використовуй print() або logging.debug() для налагодження

Немає коментарів:

Дописати коментар