Создайте приложение Flask с помощью Google Login

Создайте приложение Flask с помощью Google Login

Вы, наверное, видели опциюGoogle Login на разных сайтах. Некоторые сайты также имеют больше опций, напримерFacebook Login илиGitHub Login. Все эти параметры позволяют пользователям использовать существующие учетные записи для использования новой службы.

В этой статье вы поработаете над созданием веб-приложенияFlask. Ваше приложение позволит пользователю войти в систему, используя свою учетную запись Google вместо создания новой учетной записи. Этот метод управления пользователями дает массу преимуществ. Это будет безопаснее и проще, чем управление традиционными комбинациями имени пользователя и пароля.

Эта статья будет более простой, если вы уже понимаетеbasics of Python. Это также помогло бы немного узнать о веб-фреймворках и HTTP-запросах, но это не является строго обязательным.

К концу этой статьи вы сможете:

  • Создайте веб-приложение Flask, которое позволяет пользователям входить в систему с помощью Google.

  • Создание учетных данных клиента для взаимодействия с Google

  • Используйте Flask-Login для управления сеансом пользователя в приложении Flask

  • Лучше понять OAuth 2 и OpenID Connect (OIDC)

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

Зачем использовать логин Google для своих пользователей?

Вы можете хотеть, чтобы у отдельных пользователей были профили. Или, возможно, вы хотите предоставить функции только определенным пользователям. В любом случае вам необходимо знать, кто взаимодействует с вашим приложением. Другими словами, вам нужно будет аутентифицировать пользователей и идентифицировать их каким-то уникальным способом.

Традиционное решение заключается в использовании уникального имени пользователя и секретного пароля. Ваше приложение будет хранить эту информацию и запрашивать ее при необходимости. Однако у этого решения есть несколько недостатков:

  • Вы должны безопасно управлять паролями.

  • Вы должны реализовать любые функции, связанные с аккаунтом:

    • Двухфакторная аутентификация

    • Сброс пароля

  • Вы должны защитить от попыток злонамеренного входа в систему.

  • Ваши пользователи должны запомнить еще одно имя пользователя и пароль.

Используя логин Google для своих пользователей, вы возлагаете на них всю ответственность. Ваше приложение ожидает, пока пользователь не пройдет аутентификацию. Затем Google сообщает вашему приложению об этом пользователе. На этом этапе вы можете эффективно зарегистрировать их в своем приложении.

Вам не нужно хранить какие-либо пароли, и Google отвечает за всю безопасность.

Как приложения используют Google Login

Есть две очень популярных и важных спецификации:OAuth 2 иOpenID Connect (OIDC). OIDC построен на основе OAuth 2, добавив несколько новых идей и концепций.

Эти спецификации определяют, как стороннее приложение может получать информацию из другой службы. Обычно это предполагает получение согласия от пользователя. Чтобы немного это распаковать, давайте посмотрим, как это относится к приложению, которое вы собираетесь создать.

Вы собираетесь написать стороннее приложение, которое позволит пользователю использовать кнопкуGoogle Login для входа в систему. Для этого Google необходимо знать о вашем приложении. К счастью, вы можете зарегистрировать свое приложение в качестве клиента в Google.

Как только пользователь заходит в ваше приложение и нажимает кнопкуGoogle Login, вы можете отправить его в Google. Оттуда Google должен убедиться, что пользователь согласен передать свою электронную почту и другую информацию в ваше приложение. В случае согласия пользователя Google отправляет некоторую информацию в ваше приложение. Затем вы сохраняете эту информацию и можете ссылаться на нее позже, эффективно регистрируя пользователя.

Детали OpenID Connect

Чтобы запрашивать информацию от имени пользователя, вы должны статьclient для сервера аутентификации, также известного как поставщик. Первое, что вы поймете, если углубитесь в эти спецификации, это то, что существует множество перекрывающихся терминов и понятий.

Таким образом, как стороннее приложение (также известное как клиент), вы хотите получать информацию от поставщика от имени пользователя. Существует ряд шагов, которые позволяют этому произойти, и эти шаги должны происходить в определенном порядке. Вот почему иногда можно услышать, что OAuth 2 и OpenID Connect обозначаются какhandshake,flow илиdance.

Эти шаги, в широком смысле:

  1. Вы регистрируете стороннее приложение в качестве клиента для провайдера:

    • Вы получаете уникальные учетные данные клиента от провайдера.

    • Вы будете использовать эти учетные данные клиента для аутентификации (доказать, кто вы) провайдеру позже.

  2. Клиент отправляет запрос на URL-адрес провайдераauthorization

  3. Поставщик просит пользователя подтвердить подлинность (докажите, кто они)

  4. Поставщик просит пользователя дать согласие клиенту, действующему от его имени:

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

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

  5. Поставщик отправляет клиенту уникальный код авторизации.

  6. Клиент отправляет код авторизации обратно на URL-адрес провайдераtoken.

  7. Поставщик отправляет клиентские токены для использования с URL-адресами других поставщиков от имени пользователя.

Note: Вышеуказанные шаги относятся к потоку кода авторизации, как определено OAuth 2.

Эти шаги включают оба стандарта, упомянутых до сих пор. OpenID Connect (OIDC) построен поверх OAuth 2, добавив несколько дополнительных функций и требований, в основном связанных с процессом аутентификации. Помимо аутентификации, упомянутой в приведенном выше потоке, важными концепциями OIDC для вашего приложения являютсяprovider configuration иuserinfo endpoint.

provider configuration содержит информацию о поставщике, включая точные URL-адреса, которые необходимо использовать для потока OAuth 2. У поставщика OIDC есть стандартный URL-адрес, который можно использовать для возврата документа сstandardized fields.

userinfo endpoint вернет информацию о пользователе после того, как вы пройдете поток OAuth 2. Это будет включать их электронную почту и некоторую базовую информацию профиля, которую вы будете использовать в своем приложении. Чтобы получить эту информацию о пользователе, вам понадобится токен от провайдера, как описано в последнем шаге выше.

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

Создание клиента Google

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

Во-первых, обратите внимание, что вам понадобится аккаунт Google. У вас уже есть один, если вы используете Gmail.

Далее переходим кGoogle developers credentials page.

После этого вам может быть предложено согласиться с их условиями обслуживания. Если вы согласны с ними, нажмите кнопкуCreate credentials на следующей странице. Выберите вариант дляOAuth client ID:

Google create credentials screen shot

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

Сейчас вы будете запускать свое веб-приложение локально, поэтому вы можете установитьAuthorized JavaScript origins наhttps://127.0.0.1:5000 иAuthorized redirect URIs наhttps://127.0.0.1:5000/login/callback. Это позволит вашему локальному приложению Flask общаться с Google.

Наконец, нажмитеCreate и обратите внимание наclient ID иclient secret. Вы будете нуждаться в обоих позже.

Создание собственного веб-приложения

Теперь самое интересное, где вы применяете полученные знания для создания настоящего веб-приложения!

Давайте начнем с цели. Вы хотите создать приложение, которое позволит пользователям входить в систему под своей учетной записью Google. Это приложение должно иметь возможность получать некоторую основную информацию о пользователе из Google, например, его адрес электронной почты. Затем приложение должно хранить основную информацию о пользователе в базе данных.

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

колба

Flask - это легкий веб-фреймворк, самопровозглашенныйmicroframework. Он поставляется со встроенными инструментами для основных задач, которые будет выполнять веб-приложение, таких как маршрутизация URL-адресов и обработка HTTP-запросов.

Я выбрал Flask как пример своей популярности и простоты. Однако то, что вы узнали об OAuth 2 и OIDC, не относится к Flask. Фактически, даже библиотека, которую вы будете использовать для упрощения OAuth 2 и OIDC, может использоваться в любом коде Python. Другими словами, с некоторыми незначительными изменениями, вы можете взять то, что вы узнали здесь, и применить его к другой структуре по вашему выбору.

Колба-Войти

Другой инструмент, который вы можете использовать для упрощения работы с пользователями, - этоflask_login, который предоставляетuser session management.

Эта библиотека делает несколько вещей за кулисами и дает вам несколько инструментов, чтобы помочь пользователям. А именно, он предоставляет утилиты для вас, чтобы знать, когда пользователь вошел в систему и вышел из нее. Это делается путем управления пользовательским сеансом внутри cookie браузера.

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

OAuthLib

Существует общая фраза, которая очень верна для кода, связанного с безопасностью и соответствующего стандартам: «Не изобретай велосипед».

Стандарты OAuth 2 и OpenID Connect сложны. Посмотрите RFC и спецификации, и вы увидите. Они плотные. Одна ошибка означает, что вы можете открыть уязвимость в вашем приложении.

Таким образом, вы не собираетесь писать код для реализации этих стандартов. Вы собираетесь использовать пакет Python, который был выбран по очень специфическим критериям:

  1. Это популярная и обычно рекомендуемая библиотека. Многие другие пакеты используют эту библиотеку внутренне.

  2. Это очень активно, люди часто исправляют ошибки.

  3. Он закален в бою и существует с 2012 года.

Существуют специфичные для веб-фреймворков пакеты, которые используют эту библиотеку для более тесной интеграции с Flask, Django, Pyramid и другими. Однако, чтобы сохранить код, который вы изучаете здесь, не зависящим от фреймворка, вы будете использовать эту библиотеку напрямую без каких-либо модных упаковщиков.

Установка зависимостей

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

  • Веб-фреймворк для упрощения типичных задач веб-приложений (Flask)

  • Свободный от головной боли способ управления пользовательскими сессиями (Flask-Login)

  • Надежная библиотека OIDC (oauthlib)

Кроме того, вы будете использовать следующее:

  • База данных для хранения некоторой информации о пользователях, которые входят в систему (SQLite)

  • Удобный способ отправки HTTP-запросов в Google (requests)

  • Быстрый способ включить безопасную работу сhttps локально (pyOpenSSL)

SQLite является частью стандартной библиотеки Python, но другие пакеты - нет. Таким образом, у вас есть пара зависимостей для установки. А пока давайте просто шаг за шагом пройдем процесс создания этого приложения.

Во-первых, вам нужно установить упомянутые выше сторонние зависимости. Вы сделаете это, создав файлrequirements.txt со следующим содержанием:

requests==2.21.0
Flask==1.0.2
oauthlib==3.0.1
pyOpenSSL==19.0.0
Flask-Login==0.4.1

Note: Другие версии пакетов могут работать, но это версии, которые использовались во время написания и тестирования этой статьи.

Затем вы можете установить эти зависимости с помощьюpip, установщика пакетов Python.

Note: Обычно рекомендуется использовать виртуальные среды, если вы собираетесь устанавливать зависимости для различных приложений Python на свой компьютер. См.Python Virtual Environments: A Primer, чтобы узнать больше.

Для установки из файлаrequirements.txt выполните в терминале следующую команду:

$ pip install -r requirements.txt

Теперь вы готовы к рок-н-роллу! Давайте копаться прямо в код.

Импорт, настройка и настройка

Начните с добавления нескольких файлов для поддержки основных функций базы данных и управления пользователями. Они не будут описаны по частям, в основном потому, что подробное описание реализацииPython database - это кроличья нора, которая отвлечет нас от нашей цели.

Файлschema.sql - это просто некоторый SQL, который создаст пользовательскую таблицу в нашей базе данных. В этом файле вы можете видеть поля, которые вы будете хранить для каждого пользователя.

Следующий файл содержит наш классUser, который будет хранить и извлекать информацию из базы данных. Имя, адрес электронной почты и изображение профиля будут получены из Google, о чем вы узнаете позже в этой статье.

После того как вы создали файлыdb.py,schema.sql иuser.py из приведенного выше кода, вы можете создать новый файлapp.py. Добавьте к этому следующий импорт:

# Python standard libraries
import json
import os
import sqlite3

# Third-party libraries
from flask import Flask, redirect, request, url_for
from flask_login import (
    LoginManager,
    current_user,
    login_required,
    login_user,
    logout_user,
)
from oauthlib.oauth2 import WebApplicationClient
import requests

# Internal imports
from db import init_db_command
from user import User

Вы будете использовать все это позже, поэтому не так важно понимать каждый из них в данный момент. Следующая часть в вашемapp.py - это некоторая конфигурация:

# Configuration
GOOGLE_CLIENT_ID = os.environ.get("GOOGLE_CLIENT_ID", None)
GOOGLE_CLIENT_SECRET = os.environ.get("GOOGLE_CLIENT_SECRET", None)
GOOGLE_DISCOVERY_URL = (
    "https://accounts.google.com/.well-known/openid-configuration"
)

Вот как вы будете хранить Google Client ID и Client Secret, которые вы должны были создать ранее в этой статье. Они будут использованы позже в потоке OIDC.

Ваше приложение будет пытаться получить учетные данные клиента, читая переменные среды. Есть несколько причин для этого:

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

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

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

Tip: Вы можете установить свои учетные данные клиента как переменные среды в терминале Linux bash и терминале Mac OS X, используяexport GOOGLE_CLIENT_ID=your_client_id (аналогично дляGOOGLE_CLIENT_SECRET).

Если вы работаете в Windows, вы можете использоватьset GOOGLE_CLIENT_ID=your_client_id в командной строке.

Или выcould вставляете строки прямо сюда и сохраняете их в этих переменных. However, секрет клиентаnot должен быть передан или зафиксирован в любом публичном репозитории. Другими словами, будьте очень осторожны, чтобы не проверять этот файл, если вы вставите сюда свои настоящие учетные данные клиента.

Наконец, ниже приведен код с глобальными переменными и несколько наивных логик инициализации базы данных. Большая часть этого, кроме инициализации базы данных, является стандартным способом настройки Flask, Flask-Login и OAuthLib, о котором вы читали ранее:

# Flask app setup
app = Flask(__name__)
app.secret_key = os.environ.get("SECRET_KEY") or os.urandom(24)

# User session management setup
# https://flask-login.readthedocs.io/en/latest
login_manager = LoginManager()
login_manager.init_app(app)

# Naive database setup
try:
    init_db_command()
except sqlite3.OperationalError:
    # Assume it's already been created
    pass

# OAuth 2 client setup
client = WebApplicationClient(GOOGLE_CLIENT_ID)

# Flask-Login helper to retrieve a user from our db
@login_manager.user_loader
def load_user(user_id):
    return User.get(user_id)

Обратите внимание, что вы уже используете идентификатор клиента от Google для инициализации нашего клиентаoauthlib вWebApplicationClient.

Вы можете создать другую переменную средыSECRET_KEY, котораяFlask and Flask-Login will use, для криптографической подписи файлов cookie и других элементов.

Конечные точки веб-приложения

Теперь для забавы. Вы собираетесь написать четыре конечные точки для своего веб-приложения:

  1. Один для домашней страницы

  2. Один для начала процесса входа пользователя

  3. Один для обратного вызова, куда Google будет перенаправлять после входа пользователя

  4. Один для выхода

Эти конечные точки будут определены различными URL-адресами в вашем приложении с очень креативными именами:

  1. Домашняя страница: /

  2. Авторизоваться: /login

  3. Обратный звонок при входе: /login/callback

  4. Выйти: /logout

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

Вы добавите весь следующий код для этих конечных точек в файлapp.py. Давайте посмотрим на код каждой из этих конечных точек, по одному за раз.

домашняя страница

В этом нет ничего необычного, но вы добавите некоторую изящную логику для отображения чего-то другого, если пользователь вошел в систему. Когда они не вошли в систему, появится ссылкаGoogle Login.

Нажатие на ссылку перенаправит их на вашу конечную точку/login, которая инициирует процесс входа в систему. После успешного входа на главной странице теперь будет отображаться как электронная почта пользователя Google, так и его общедоступная фотография профиля Google!

Без лишних слов вы можете начать добавлять код в свой файлapp.py:

@app.route("/")
def index():
    if current_user.is_authenticated:
        return (
            "

Hello, {}! You're logged in! Email: {}

" "

Google Profile Picture:

" 'Google profile pic
' 'Logout'.format( current_user.name, current_user.email, current_user.profile_pic ) ) else: return 'Google Login'

Вы заметите, что вы возвращаете HTML в виде строки, которую Flask сможет обработать. current_user.is_authenticated - прекрасное дополнение к библиотекеFlask-Login. Это простой способ определить, вошел ли в систему текущий пользователь, взаимодействующий с вашим приложением, или нет. Это позволяет вам применять условную логику. В этом случае отображается некоторая информация о пользователе, которую вы сохранили, если он вошел в систему.

Вы можете получить поля из записи в базе данных для пользователя, просто обращаясь к ним как к атрибутам объектаcurrent_user, напримерcurrent_user.email. Это еще одно добавлениеFlask-Login.

Авторизоваться

Теперь давайте перейдем к потоку OAuth 2. КнопкаGoogle Login сверху будет перенаправлять на эту конечную точку. Первый шаг в этом процессе - выяснить, где находится конечная точка авторизации OAuth 2 Google.

Вот где границы между тем, что определено OAuth 2 и OpenID Connect (OIDC), начинают стираться. Как обсуждалось ранее, OIDC имеет стандартную конечную точку дляprovider configuration, которая содержит набор информации OAuth 2 и OIDC. Документ с этой информацией везде обслуживается стандартной конечной точкой.well-known/openid-configuration.

Предполагая, что вы скопировали предыдущий код, определяющийGOOGLE_DISCOVERY_URL, вот простая и наивная функция для получения конфигурации поставщика Google:

def get_google_provider_cfg():
    return requests.get(GOOGLE_DISCOVERY_URL).json()

Tip: Чтобы сделать это более надежным, вы должны добавить обработку ошибок в вызов Google API на случай, если API Google вернет ошибку, а не действительный документ конфигурации поставщика.

Поле из необходимого вам документа конфигурации провайдера называетсяauthorization_endpoint. Он будет содержать URL-адрес, который необходимо использовать для запуска потока OAuth 2 с Google из вашего клиентского приложения.

Вы можете поместить всю эту логику вместе со следующим кодом:

@app.route("/login")
def login():
    # Find out what URL to hit for Google login
    google_provider_cfg = get_google_provider_cfg()
    authorization_endpoint = google_provider_cfg["authorization_endpoint"]

    # Use library to construct the request for Google login and provide
    # scopes that let you retrieve user's profile from Google
    request_uri = client.prepare_request_uri(
        authorization_endpoint,
        redirect_uri=request.base_url + "/callback",
        scope=["openid", "email", "profile"],
    )
    return redirect(request_uri)

К счастью,oauthlib упрощает фактический запрос в Google. Вы использовали предварительно настроенныйclient, которому уже дали свой идентификатор клиента Google. Затем вы предоставили перенаправление, которое вы хотите использовать Google. Наконец, вы запросили у Google количество OAuth 2scopes.

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

Note:openid - это необходимая область, чтобы сообщить Google, что нужно инициировать поток OIDC, который аутентифицирует пользователя, заставляя его войти в систему. OAuth 2 на самом деле не стандартизирует, как происходит аутентификация, поэтому в этом случае это необходимо для нашего потока.

Логин Обратный звонок

Давайте сделаем это по частям, так как это немного сложнее, чем предыдущие несколько конечных точек.

Как только вы перенаправляете на конечную точку авторизации Google, многое происходит на стороне Google.

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

В качестве напоминания, вот шаги OIDC, о которых вы читали ранее:

  1. Вы регистрируете стороннее приложение в качестве клиента для провайдера.

  2. Клиент отправляет запрос на URL-адрес провайдераauthorization.

  3. Поставщик просит пользователя пройти аутентификацию (доказать, кто он).

  4. Поставщик просит пользователя дать согласие клиенту, действующему от его имени.

  5. Провайдер отправляет клиенту уникальный код авторизации

  6. Клиент отправляет код авторизации обратно на URL-адрес провайдераtoken

  7. Поставщик отправляет клиентские токены для использования с другими URL-адресами от имени пользователя.

Когда Google отправит обратно этот уникальный код, он отправит его на эту конечную точку обратного вызова для входа в приложение. Итак, ваш первый шаг - определить конечную точку и получитьcode:

@app.route("/login/callback")
def callback():
    # Get authorization code Google sent back to you
    code = request.args.get("code")

Следующее, что вы собираетесь сделать, - это отправить этот код обратно на конечную точку Googletoken. После того, как Google проверит ваши учетные данные клиента, они отправят вам обратно токены, которые позволят вам пройти аутентификацию на других конечных точках Google от имени пользователя, включая конечную точкуuserinfo, о которой вы читали ранее. В вашем случае вы только просили просмотреть основную информацию профиля, так что это единственное, что вы можете сделать с токенами.

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

# Find out what URL to hit to get tokens that allow you to ask for
# things on behalf of a user
google_provider_cfg = get_google_provider_cfg()
token_endpoint = google_provider_cfg["token_endpoint"]

oauthlib несколько раз придет вам на помощь в следующем блоке кода. Во-первых, вам нужно создать запрос токена. После создания запроса вы будете использовать библиотекуrequests для его фактической отправки. Затемoauthlib еще раз поможет вам с разбором токенов из ответа:

# Prepare and send a request to get tokens! Yay tokens!
token_url, headers, body = client.prepare_token_request(
    token_endpoint,
    authorization_response=request.url,
    redirect_url=request.base_url,
    code=code
)
token_response = requests.post(
    token_url,
    headers=headers,
    data=body,
    auth=(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET),
)

# Parse the tokens!
client.parse_request_body_response(json.dumps(token_response.json()))

Теперь, когда у вас есть необходимые инструменты для получения информации о профиле пользователя, вам нужно попросить об этом Google. К счастью, OIDC определяет конечную точку информации о пользователе, и ее URL для данного поставщика стандартизирован в конфигурации поставщика. Вы можете узнать местоположение, проверив полеuserinfo_endpoint в документе конфигурации провайдера. Затем вы можете использоватьoauthlib, чтобы добавить токен в свой запрос, и использоватьrequests для его отправки:

# Now that you have tokens (yay) let's find and hit the URL
# from Google that gives you the user's profile information,
# including their Google profile image and email
userinfo_endpoint = google_provider_cfg["userinfo_endpoint"]
uri, headers, body = client.add_token(userinfo_endpoint)
userinfo_response = requests.get(uri, headers=headers, data=body)

Следующий шаг в вашем путешествии - разобрать ответ от конечной точкиuserinfo. Google использует необязательное полеemail_verified, чтобы подтвердить, что не только пользователь создал учетную запись, но и подтвердил адрес электронной почты для завершения создания учетной записи. Обычно безопасно проверять эту проверку, так как это еще один уровень безопасности, который предлагает Google.

При этом вы проверите это, и если Google скажет, что пользователь подтвержден, то вы проанализируете его информацию. 4 части базовой информации о вашем профиле:

  1. sub: тема, уникальный идентификатор пользователя в Google

  2. email: адрес электронной почты пользователя в Google

  3. picture: изображение общедоступного профиля пользователя в Google

  4. given_name: имя и фамилия пользователя в Google

Все это приводит к следующему коду:

# You want to make sure their email is verified.
# The user authenticated with Google, authorized your
# app, and now you've verified their email through Google!
if userinfo_response.json().get("email_verified"):
    unique_id = userinfo_response.json()["sub"]
    users_email = userinfo_response.json()["email"]
    picture = userinfo_response.json()["picture"]
    users_name = userinfo_response.json()["given_name"]
else:
    return "User email not available or not verified by Google.", 400

Заключительные шаги в этом обратном вызове:

  1. Создайте пользователя в своей базе данных с информацией, которую вы только что получили от Google

  2. Начните сеанс пользователя, зарегистрировав этого пользователя в

  3. Отправьте пользователя обратно на домашнюю страницу (где вы теперь будете отображать информацию его общедоступного профиля)

Код для выполнения этих шагов выглядит следующим образом:

# Create a user in your db with the information provided
# by Google
user = User(
    id_=unique_id, name=users_name, email=users_email, profile_pic=picture
)

# Doesn't exist? Add it to the database.
if not User.get(unique_id):
    User.create(unique_id, users_name, users_email, picture)

# Begin user session by logging the user in
login_user(user)

# Send user back to homepage
return redirect(url_for("index"))

Итак, что вы делаете здесь, это создаете новую строку в вашей базе данных для пользователя, если он еще не существует. Затем вы начинаете сеанс с помощью Flask-Login.

Выйти

Конечная точка выхода из системы содержит гораздо меньше кода, чем последние несколько конечных точек. Вы просто вызываете функцию выхода из системы и перенаправляете обратно на домашнюю страницу. Сделано и сделано. Вот:

@app.route("/logout")
@login_required
def logout():
    logout_user()
    return redirect(url_for("index"))

Здесь важно упомянуть@login_requireddecorator. Это еще один инструмент из набора инструментовFlask-Login, который гарантирует, что только зарегистрированные пользователи могут получить доступ к этой конечной точке. Вы можете использовать это, если только зарегистрированные пользователи должны иметь доступ к чему-либо. В этом случае только зарегистрированные пользователи могут выйти из системы.

Тестирование вашего приложения локально

Вы можете запустить приложение Flask на локальном компьютере, чтобы проверить процесс входа в систему, добавив последний код вapp.py:

if __name__ == "__main__":
    app.run(ssl_context="adhoc")

Вы можете запустить приложение Flask с помощью следующей команды в своем терминале:

$ python app.py

Note: Из-за простой логики инициализации базы данных, при первом запуске этой команды будет создана база данных. Чтобы запустить приложение, вы должны выполнить ту же командуagain.

Flask должен печатать на вашем терминале, где работает сервер разработки. Это должно бытьhttps://127.0.0.1:5000/.

Обратите внимание, что сервер разработки Flask работает локальноand с использованиемhttps для обеспечения зашифрованного соединения с Google. Это достигается с помощью аргументаssl_context="adhoc" дляapp.run в приведенном выше коде. Для этого у вас должен быть установлен пакетPyOpenSSL.

Обратной стороной является то, что используемый сертификат генерируется «на лету», поэтому, когда вы перейдете кhttps://127.0.0.1:5000/ в своем браузере, он, вероятно, выдаст вам большой экран с предупреждением о том, что ваше соединение небезопасно или не конфиденциально. Вы можете эффективно игнорировать эти предупреждения.

Пройдя мимо экрана предупреждения, вы должны увидеть единственную кнопку с надписьюGoogle Login. Нажатие на него отправит вас к официальному логину Google. После того, как вы войдете в систему, Google предложит вам согласиться на получение «сторонним приложением» доступа к вашей электронной почте и данным профиля.

После того, как вы дадите согласие, вы будете перенаправлены обратно в приложение Flask, где на странице должны отображаться ваш адрес электронной почты Google и изображение общедоступного профиля! Наконец, кнопкаLogout позволяет вам выйти из системы.

Заключение

Разрешение пользователям использовать свои существующие учетные записи для входа в веб-приложение имеет много преимуществ. Самое главное, безопасность и сложность управления учетными записями не должны ложиться на ваши плечи. Это освобождает вас от необходимости писать новое модное веб-приложение, не беспокоясь о мельчайших подробностях двухфакторной аутентификации и тому подобного.

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

Ваш следующий шаг может быть следующим:

  • Переработать инициализацию базы данных, чтобы она происходила отдельно от запуска приложения

  • Отделите HTML / CSS от кода Python для более удобного управления:

    • Вы можете использоватьtemplates.

    • Вы также можете загружать статические файлы (например, JS и CSS)from elsewhere.

  • Разместите ваше приложение в облаке

  • Купить доменное имя

  • Используйте настоящий сертификат SSL и избавьтесь от этого надоедливого предупреждения

В этой статье вы ознакомились с основами OAuth 2 и OpenID Connect. Вы видели, как использовать хорошо известные пакеты Python для создания веб-приложения, которое позволяет пользователям входить в систему с использованием существующей учетной записи Google. Самое главное, у вас есть пример кода, который служит отличной отправной точкой для вашего следующего веб-приложения!

Related