Аутентификация пользователя – основная функция в веб-приложения, чтобы люди могли создавать и получать доступ свои собственные аккаунты. К сожалению, аутентификацию не всегда легко настроить и есть много способов неправильно реализовать вход и выход из системы функции.
В этом руководстве рассказывается, как использовать безопасная служба аутентификации личности называется Okta , который предоставляется бесплатно до 1000 активные учетные записи пользователей, чтобы легко обрабатывать пользовательские данные во Flask Приложения.
Наши инструменты
Python 3 настоятельно рекомендуется для создания приложений, и это учебник был построен с помощью Python 3.7, хотя более ранние версии Python 3 тоже должно работать нормально. В дополнение к Python 3.x мы также будем использовать:
- Веб-фреймворк Flask версия 1.0.2
- Flask-OIDC , где
- OIDC означает «OpenID Connect». Он обеспечивает поддержку использования OpenID
- Подключите в приложениях Flask.
- Вспомогательная библиотека Python Okta
- Бесплатная учетная запись разработчика Okta
Весь код в этом сообщении в блоге предоставляется с открытым исходным кодом под Лицензия MIT на GitHub под каталог flask-auth-okta блога-кода-примеров репозиторий. Используйте и злоупотребляйте исходным кодом для приложений, которые вы хотите построить.
Установка зависимостей
Создайте новый Python virtualenv для этого проекта:
python3 -m venv flaskauth
Активируйте виртуальную среду с помощью скрипта activate
:
. ./flaskauth/bin/activate
Командная строка должна измениться после активации:
Помните, что вам нужно будет активировать virtualenv в каждом терминале окно, в котором вы хотите использовать зависимости, содержащиеся в этом virtualenv.
Теперь мы можем установить Flask и зависимости Okta.
pip install flask>=1.0.2 flask-oidc>=1.4.0 okta==0.0.4
Найдите вывод, аналогичный приведенному ниже, чтобы убедиться, что зависимости Успешно установлен:
... Collecting idna<2.8,>=2.5 (from requests>=2.5.3->okta) Downloading https://files.pythonhosted.org/packages/4b/2a/0276479a4b3caeb8a8c1af2f8e4355746a97fab05a372e4a2c6a6b876165/idna-2.7-py2.py3-none-any.whl (58kB) 100% |████████████████████████████████| 61kB 16.6MB/s Collecting urllib3<1.24,>=1.21.1 (from requests>=2.5.3->okta) Downloading https://files.pythonhosted.org/packages/bd/c9/6fdd990019071a4a32a5e7cb78a1d92c53851ef4f56f62a3486e6a7d8ffb/urllib3-1.23-py2.py3-none-any.whl (133kB) 100% |████████████████████████████████| 143kB 14.0MB/s Installing collected packages: MarkupSafe, Jinja2, click, itsdangerous, Werkzeug, flask, pyasn1, pyasn1-modules, rsa, httplib2, six, oauth2client, flask-oidc, chardet, certifi, idna, urllib3, requests, python-dateutil, okta Running setup.py install for MarkupSafe ... done Running setup.py install for itsdangerous ... done Running setup.py install for httplib2 ... done Running setup.py install for flask-oidc ... done Running setup.py install for okta ... done Successfully installed Jinja2-2.10 MarkupSafe-1.0 Werkzeug-0.14.1 certifi-2018.8.24 chardet-3.0.4 click-6.7 flask-1.0.2 flask-oidc-1.4.0 httplib2-0.11.3 idna-2.7 itsdangerous-0.24 oauth2client-4.1.3 okta-0.0.4 pyasn1-0.4.4 pyasn1-modules-0.2.2 python-dateutil-2.7.3 requests-2.19.1 rsa-4.0 six-1.11.0 urllib3-1.23
Мы установили необходимые нам Flask и зависимости Okta, так что приступим к созданию приложение Flask.
Создание базового приложения Flask
Первый шаг перед добавлением аутентификации в наше приложение Flask – написать некоторые функции строительных лесов. Аутентификация подключится к эти функции, такие как вход
и выход
, для обеспечения аутентификации процесс работает правильно.
Создайте каталог для своего проекта с именем thundercats
. Почему thundercats
? Почему не Thundercats?
В thundercats
непосредственно создайте файл с именем app.py
с следующее исходное содержание:
# imports for Flask from flask import Flask, Response app = Flask(__name__) @app.route("/lair") def lair(): return Response("Thundercats (supposed to be hidden) lair.") @app.route("/") def landing_page(): return Response("Thundercats, Thundercats, hoooooooooooo!")
Мы можем запустить наше приложение Flask, используя следующую команду:
set FLASK_APP=app.py flask run
Перейдите на localhost: 5000 в своем веб-браузере, и вы должны увидеть:
Теперь идем в наше «скрытое логово» по адресу localhost: 5000/lair/. В конце концов это страница должна требовать аутентификации для доступа, но пока она отображается без каких-либо проблем со входом:
Отлично, наше базовое приложение запущено, давайте перейдем к аутентификации. функциональность.
Auth-as-a-Service
Перейдите на страницу регистрации разработчиков Okta .
Зарегистрируйте новую учетную запись или войдите в существующую.
Интересный момент в процессе регистрации разработчиков Okta заключается в том, что теперь вы следует проверить свою электронную почту, чтобы завершить создание учетной записи. Ищите электронную почту как этот:
Нажмите кнопку «Войти» и войдите в учетную запись разработчика, используя временный пароль, указанный в электронном письме. Установите новый пароль и вызовите вопрос. Затем выберите изображение, соответствующее процессу входа в вашу учетную запись.
Нажмите кнопку «Создать учетную запись», и вы перейдете к Панель разработчика Okta.
Найдите «URL-адрес организации», как показано на следующем рисунке.
Мы собираемся использовать этот URL в нашем секретном файле учетных данных, чтобы наше веб-приложение Flask может правильно подключаться к службе Okta.
Создайте новый файл в каталоге вашего проекта с именем openidconnect_secrets.json
со следующим содержимым:
{ "web": { "client_id": "{{ OKTA_CLIENT_ID }}", "client_secret": "{{ OKTA_CLIENT_SECRET }}", "auth_uri": "{{ OKTA_ORG_URL }}/oauth2/default/v1/authorize", "token_uri": "{{ OKTA_ORG_URL }}/oauth2/default/v1/token", "issuer": "{{ OKTA_ORG_URL }}/oauth2/default", "userinfo_uri": "{{ OKTA_ORG_URL }}/oauth2/default/userinfo", "redirect_uris": [ "http://localhost:5000/oidc/callback" ] } }
Замените четыре заполнителя {{OKTA_ORG_URL}}
значением URL организации. найдено в вашей панели управления. Мы заполним остальные заполнители с помощью фактические значения по мере прохождения обучения. Мой Файл openidconnect_secret.json
в настоящее время будет иметь следующие значения основаны на моем URL-адресе организации панели разработчика. Помните, что значения ваших URL будут другими!
{ "web": { "client_id": "{{ OKTA_CLIENT_ID }}", "client_secret": "{{ OKTA_CLIENT_SECRET }}", "auth_uri": "https://dev-860408.oktapreview.com/oauth2/default/v1/authorize", "token_uri": "https://dev-860408.oktapreview.com/oauth2/default/v1/token", "issuer": "https://dev-860408.oktapreview.com/oauth2/default", "userinfo_uri": "https://dev-860408.oktapreview.com/oauth2/default/userinfo", "redirect_uris": [ "http://localhost:5000/oidc/callback" ] } }
Хорошо, у нас настроена учетная запись Okta, поэтому мы можем добавить код аутентификации для нашего приложения Flask.
Подключение Flask к Okta
Нам нужно подключить наш код Flask к нашей новой учетной записи Okta. В рекомендуемый способ включения переменных, таких как учетные данные в приложении Flask проходит через обработка конфигурации поэтому мы будем использовать это в нашей учетной записи.
Обновите код Flask, указав следующие выделенные строки.
# imports for both Flask and Okta connection from os import environ from flask import Flask, Response from flask_oidc import OpenIDConnect from okta import UsersClient app = Flask(__name__) # secret credentials for Okta connection app.config["OIDC_CLIENT_SECRETS"] = "openidconnect_secrets.json" app.config["OIDC_COOKIE_SECURE"] = False app.config["OIDC_CALLBACK_ROUTE"] = "/oidc/callback" app.config["OIDC_SCOPES"] = ["openid", "email", "profile"] app.config["SECRET_KEY"] = environ.get("SECRET_KEY") app.config["OIDC_ID_TOKEN_COOKIE_NAME"] = "oidc_token" # instantiate OpenID client to handle user session oidc = OpenIDConnect(app) # Okta client will determine if a user has an appropriate account okta_client = UsersClient(environ.get("OKTA_ORG_URL"), environ.get("OKTA_AUTH_TOKEN")) @app.route("/lair") def lair(): return Response("Thundercats (supposed to be hidden) lair.") @app.route("/") def landing_page(): return Response("Thundercats, Thundercats, hoooooooooooo!")
Сначала мы добавляем три строки импорта, одну для извлечения значений из окружения. переменные, и следующие два импорта, чтобы можно было использовать OpenID Подключи и окта в нашем приложении.
Остальной новый код задает конфигурацию приложения Flask. значения, которые можно использовать для создания экземпляров OpenID Connect и Клиенты Okta.
OIDC_CLIENT_SECRETS
: расположение файла секретов OpenID Connect.OIDC_COOKIE_SECURE
: разрешает режим разработки для тестирования входа пользователя и- регистрация без SSL. Ваше приложение должно установить для него значение
True
в - производственное приложение.
OIDC_CALLBACK_ROUTE
: URL-адрес в веб-приложении для обработки логинов пользователей.OIDC_SCOPES
: какие данные запрашивать о пользователе при входе в систему. Наши- приложение запрашивает основную информацию об электронной почте, имени и профиле
SECRET_KEY
: это параметр Flask для обеспечения безопасности сеансов. Ключ- никогда не должны публиковаться, иначе пользовательские сеансы вашего веб-приложения будут
- скомпрометирован.
Но где мы можем взять эти значения конфигурации приложения? Мы необходимо получить их из нашей учетной записи Okta, так что вернитесь на панель инструментов для создания нового приложения OpenID Connect.
Приложения OpenID Connect используют идентификатор клиента и секрет клиента в место традиционных логинов и паролей. Идентификатор клиента и секрет клиента скажет вашему серверу авторизации распознать ваш применение. Нажмите кнопку «Добавить приложение».
На экране нового приложения выберите «Интернет» и нажмите «Далее».
На следующей странице есть множество вариантов конфигурации, но только несколько значений, которые нам нужно заполнить, прежде чем мы сможем получить наши учетные данные. Набор следующие значения для Name
, базовых URI
и URI перенаправления входа
свойства:
Это три значения, которые вам нужно заполнить, поэтому сохраните приложение для его создания.
На следующей странице прокрутите вниз, чтобы найти своего клиента и секретные ключи.
Скопируйте и вставьте идентификатор клиента и секрет клиента в следующий выделенные строки для замены {{OKTA_CLIENT_ID}}
и {{OKTA_CLIENT_SECRET}}
заполнители.
{ "web": { "client_id": "{{ OKTA_CLIENT_ID }}", "client_secret": "{{ OKTA_CLIENT_SECRET }}", "auth_uri": "https://dev-860408.oktapreview.com/oauth2/default/v1/authorize", "token_uri": "https://dev-860408.oktapreview.com/oauth2/default/v1/token", "issuer": "https://dev-860408.oktapreview.com/oauth2/default", "userinfo_uri": "https://dev-860408.oktapreview.com/oauth2/default/userinfo", "redirect_uris": [ "http://localhost:5000/oidc/callback" ] } }
Сохраните файл и убедитесь, что он не контролируется версиями, поскольку секретные ценности должны оставаться в секрете.
Перед обновлением у нас есть еще один шаг на панели инструментов разработчика Okta наше приложение Flask с кодом аутентификации: создание токен аутентификации API . Перейдите на вкладку API.
Нажмите кнопку «Создать токен».
Назовите токен ThunderFlaskCatsToken
и скопируйте его. Сохраните токен где-нибудь безопасно, поскольку мы больше не сможем получить к нему доступ через панель управления. Мы собираются использовать этот токен при настройке среды OKTA_AUTH_TOKEN
переменная в следующем разделе этого руководства.
Хорошо, наконец-то у нас есть вся конфигурация сервиса Okta и токены в наш файл openidconnect_secret.json
, который нам нужен для завершения нашего приложения.
Защита логова
Наша конфигурация настроена, поэтому обновите файл app.py
следующим образом: выделенные строки:
# imports for both Flask and Okta connection from os import environ from flask import Flask, Response, redirect, g, url_for from flask_oidc import OpenIDConnect from okta import UsersClient app = Flask(__name__) # secret credentials for Okta connection app.config["OIDC_CLIENT_SECRETS"] = "openidconnect_secrets.json" app.config["OIDC_COOKIE_SECURE"] = False app.config["OIDC_CALLBACK_ROUTE"] = "/oidc/callback" app.config["OIDC_SCOPES"] = ["openid", "email", "profile"] app.config["SECRET_KEY"] = environ.get("SECRET_KEY") app.config["OIDC_ID_TOKEN_COOKIE_NAME"] = "oidc_token" # instantiate OpenID client to handle user session oidc = OpenIDConnect(app) # Okta client will determine if a user has an appropriate account okta_client = UsersClient(environ.get("OKTA_ORG_URL"), environ.get("OKTA_AUTH_TOKEN")) @app.before_request def before_request(): if oidc.user_loggedin: g.user = okta_client.get_user(oidc.user_getfield("sub")) else: g.user = None @app.route("/lair") @oidc.require_login def lair(): return Response("Thundercats (supposed to be hidden) lair.") @app.route("/") def landing_page(): return Response("Thundercats, Thundercats, hoooooooooooo!") @app.route("/login") @oidc.require_login def login(): return redirect(url_for(".lair")) @app.route("/logout") def logout(): oidc.logout() return redirect(url_for(".landing_page"))
Вышеупомянутые новые выделенные строки проверяют, вошел ли пользователь в систему. перед каждым запросом. Если для маршрута требуется авторизованный пользователь из-за декоратор @ oidc.require_login
, тогда пользователь будет перенаправлен на войдите на страницу. Мы также добавили маршруты в разделах /login
и /logout
, чтобы можно войти и выйти из приложения.
Задайте три переменные среды, чтобы наше приложение могло использовать их, когда мы запустить его. Убедитесь, что заполнители ORG_URL
и AUTH_TOKEN
установлены с ваше фактическое значение URL-адреса организации и токен аутентификации на панели инструментов разработчика Okta.
В командной строке выполните следующие команды, не забудьте заменить любые значения-заполнители с вашими собственными токенами и URL-адресами:
# this tells Flask we want to run the built-in server in dev mode export FLASK_ENV=development # make sure to use a very long random string here that cannot be guessed export SECRET_KEY='a very long string with lots of numbers and letters' # this is the same Org URL found on your developer dashboard # for example, https://dev-860408.oktapreview.com export OKTA_ORG_URL='ORG_URL' # this is the API authentication token we created export OKTA_AUTH_TOKEN='AUTH_TOKEN'
Теперь перезапустите приложение Flask:
set FLASK_APP=app.py flask run
Вы должны быть в хорошей форме, если сервер разработки запускается с выводом как это:
(flaskauth)$ flask run * Environment: development * Debug mode: on * Running on http://127.0.0.1:5000/ (Press CTRL+C to quit) * Restarting with stat * Debugger is active! * Debugger PIN: 415-920-546
Направляйтесь на localhost: 5000 в браузере, в который вы еще не вошли. ваша учетная запись Okta (отлично работает окно в режиме инкогнито вашего веб-браузера).
Давайте протестируем функцию перенаправления, когда мы попытаемся перейти в /lair
маршрут, перейдя на localhost: 5000/lair. Мы перенаправляемся на Okta страница авторизации.
Введите имя пользователя и пароль разработчика Okta, чтобы войти в приложение. Для целей разработки это подойдет для тестирования, но, очевидно, в производственное приложение, вы создадите другие учетные записи для входа пользователей.
Давайте настроим еще один бит в нашем приложении, чтобы исправить явное отсутствие радость от успешного завершения кода аутентификации для этого руководство. Обновите две выделенные строки, чтобы они соответствовали тому, что находится в коде блок ниже:
# imports for both Flask and Okta connection from os import environ from flask import Flask, Response, redirect, g, url_for from flask_oidc import OpenIDConnect from okta import UsersClient app = Flask(__name__) # secret credentials for Okta connection app.config["OIDC_CLIENT_SECRETS"] = "openidconnect_secrets.json" app.config["OIDC_COOKIE_SECURE"] = False app.config["OIDC_CALLBACK_ROUTE"] = "/oidc/callback" app.config["OIDC_SCOPES"] = ["openid", "email", "profile"] app.config["SECRET_KEY"] = environ.get("SECRET_KEY") app.config["OIDC_ID_TOKEN_COOKIE_NAME"] = "oidc_token" # instantiate OpenID client to handle user session oidc = OpenIDConnect(app) # Okta client will determine if a user has an appropriate account okta_client = UsersClient(environ.get("OKTA_ORG_URL"), environ.get("OKTA_AUTH_TOKEN")) @app.before_request def before_request(): if oidc.user_loggedin: g.user = okta_client.get_user(oidc.user_getfield("sub")) else: g.user = None @app.route("/lair") @oidc.require_login def lair(): thundercats_lair = 'Thundercats, hoooo! Thundercats now hidden lair.
' return Response(thundercats_lair) @app.route("/") def landing_page(): return Response("Thundercats, Thundercats, hoooooooooooo!") @app.route("/login") @oidc.require_login def login(): """Force user to login and then redirect them to the lair. """ return redirect(url_for(".lair")) @app.route("/logout") def logout(): oidc.logout() return redirect(url_for(".landing_page"))
Обновите страницу логова.
Хорошо, только немного лучше! Перейдите на localhost: 5000/выйдите из системы отменить аутентификацию вашего пользователя. Когда вы снова идете на localhost: 5000/lair, вы теперь придется повторно пройти аутентификацию.
Что теперь?
Мы только что создали пример приложения Flask с аутентификацией пользователя через Okta API .
Затем попробуйте следующие руководства, чтобы добавить другие функции в свой Приложение Flask:
- Ответ на текстовые SMS-сообщения с помощью Python и Flask
- Как добавить размещенный мониторинг в веб-приложения Flask
- Разработка и запуск приложений Flask в контейнерах Docker
Вы также можете определить, что кодировать дальше в своем проекте Python, прочитав страница содержания Full Stack Python.
Вопросов? Свяжитесь со мной через Twitter @fullstackpython или @mattmakai . Я также на GitHub с имя пользователя mattmakai .
Что-то не так с этим сообщением? Вилка источник этой страницы на GitHub и отправьте запрос на перенос.