Практически любое веб-приложение предоставляет возможность авторизации пользователя с использованием учетной записи пользователя, в каком либо из известных социальных сервисов.
Магия авторизации происходит строго по протоколу OAuth 1.0а и OAuth 2.0 и значительно упрощает жизнь и владельцу веб-приложения и самому пользователю.
Остается сущая мелочь, реализовать нужный протокол применительно к конкретному веб-приложению. Регистрация и вход в веб сервис TheOnlyPage с использованием учетных записей Facebook, Google, LinkedIn и Microsoft Live работают благодаря python библиотеке Authomatic.
Согласно документации Authomatic обладает следующими замечательными особенностями:
- Слабая связанность.
- Компактный, но мощный интерфейс
- Единственная, причем необязательная зависимость: библиотека pytyon-openid
- CSRF защита
- Благодаря адаптерам нет привязки к конкретному фреймворку. Сразу из коробки поддерживается Django, Flask и Webapp2.
- Возможность включать новые появляющиеся протоколы авторизации и аутентификации
- Запросы к программному интерфейсу (API) провайдера — проще некуда.
- Поддержка асинхронных запросов
- В качестве бонуса javascript-библиотека
- Сразу из коробки поддержка:
- OAuth 1.0a провайдеров: Bitbucket, Flickr, Meetup, Plurk, Twitter, Tumblr, UbuntuOne,Vimeo, Xero, Xing and Yahoo
- OAuth 2.0 провайдеров: Behance, Bitly, Cosm, DeviantART, Facebook, Foursquare,GitHub, Google, LinkedIn, PayPal, Reddit, Viadeo, VK, WindowsLive, Yammer и Yandex.
- python-openid и OpenID основанного на Google App Engine
Вдобавок ко всему отмечается, что библиотека находится на очень раннем этапе создания, и практически не протестирована.
Несмотря на такое самокритичное заявление, если обратиться к демонстрационной страничке, можно убедиться что библиотека обеспечивает беспроблемную работу со всевозможными провайдерами OAuth 1.0a и OAuth 2.0.
Качественная документация даёт достаточно информации для использования библиотеки совместно с фреймворками: Django, Flask, Pyramid и Webapp2.
Проиллюстрируем работу с Authomatic на примере из реальной жизни. Для того чтобы зарегистрироваться / войти в веб-сервис TheOnlyPage посредством учетной записи Facebook, Google, LinkedIn и Microsoft Live достаточно кликнуть по соответствующей кнопке, на странице входа в сервис:
Процесс авторизации реализован при помощи библиотеки Authomatic. При этом TheOnlyPage работает на фреймворке Flask. Для того чтобы задействовать библиотеку Authomatic в связке с фреймворком Flask, при условии что библиотека уже присутствует в рабочем пространстве, нужно:
- Зарегистрировать свое приложение в каждом из OAuth-провайдеров.
- Добавить параметры OAuth-провайдеров в конфигурационный файл.
- Инициировать базовый объект
authomatic
параметрами, хранящимися в конфигурационном файле. - Создать представление, которое выполнит запрос к провайдеру и получит от него результат.
Проделаем эти 4 нехитрых шага:
Регистрация приложения
У каждого провайдера свои особенности регистрации. Адреса регистрации приложения
для Facebook: developers.facebook.com/apps
для Google: console.developers.google.com/project
для LinkedIn: www.linkedin.com/secure/developer
для Microsoft Live: account.live.com/developers/applications/create
Некоторые параметры, которые потребуется указать, у разных провайдеров могут отличаться, но среди остальных параметров обязательно присутствуют:
- адреса нашего сервиса, с которых разрешен редирект с запросом к провайдеру
- адрес, по которому провайдер возвращает пользователя к нашему сервису после предоставления доступа
- адрес, по которому провайдер возвращает пользователя к нашему сервису при отказе в предоставлении доступа
В случае использования библиотеки Authomatic в 1-м и 2-м случае удобно указать один и тот же адрес, так для соответствующих провайдеров будем использовать адреса:
www.theonlypage.com/login/facebook
www.theonlypage.com/login/google
www.theonlypage.com/login/linkedin
www.theonlypage.com/login/microsoft
Также на страничке регистрации приложения у провайдера, нам надо получить код пользователя и секретный ключ, в терминах различных провайдеров они соответственно называются:
код пользователя | секретный ключ | |
---|---|---|
App ID | App Secret | |
Client ID | Client secret | |
API Key | Secret Key | |
Microsoft Live | Client ID | Client secret |
Кроме того, в разделе регистрации приложения у провайдера, мы должны выяснить под каким названием фигурируют нужные нам данные. Например, адрес электронной почты пользователя обозначается:
для Facebook: email
для Google: email
для LinkedIn: r_emailaddress
для Microsoft Live: wl.emails
После того как приложение зарегистрировано во всех провайдерах, адреса редиректа указаны, код пользователя и секретный ключ получены, есть ясность как именуются данные применительно к каждому провайдеру, можно переходить к настройке конфигурационного файла.
Определение конфигурации OAuth провайдеров
В стандартный конфигурационный файл flask-приложения нужно добавить словарь содержащий параметры всех провайдеров:
OAUTH_CONFIG = {
'facebook': {
'class_': oauth2.Facebook,
'consumer_key': 123456789012345',
'consumer_secret': ' edcba987654321012345679abcdedcab',
'scope': ['email',],
},
'google': {
'class_': oauth2.Google,
'consumer_key': '123456789098.apps.googleusercontent.com',
'consumer_secret': ' ABcDEFgiJKLmNOPQRStUVWxyz ',
'scope': ['email',],
},
'linkedin': {
'class_': oauth2.LinkedIn,
'consumer_key': ' ABC123df45GIJ6h ',
'consumer_secret': ‘zyx987vutSRQponM ',
'scope': ['r_emailaddress',],
},
'microsoft': {
'class_': oauth2.WindowsLive,
'consumer_key': '0000000012345A67',
'consumer_secret': ' ABcDe123fgHIJK45LmnO6789PQrS0tUVXyz ',
'scope': ['wl.emails',],
},
}
Как видим каждому провайдеру ставится в соответствие словарь со следующими атрибутами:
class_
: входящий в состав библиотеки Authomatic класс, соответствующий очередному провайдеру;
consumer_key
: код пользователя у очередного провайдера;
consumer_secret
: секретный ключ очередного провайдера;
scope
: список данных, которые предполагается запрашивать у очередного провайдера.
Предварительные установки сделаны.
Инициация базового объекта authomatic
Происходит очень просто, с указаним конфигурационных данных и секретной строки:
from authomatic import Authomatic
from config import OAUTH_CONFIG
authomatic = Authomatic(OAUTH_CONFIG, ‘very secret string', report_errors=False)
Создание представления
Осталось создать представление, которое:
- соответствует интернет адресу с которого осуществляется редирект запроса данных к провайдеру и получение данных от провайдера;
- осуществляет получение электронного адреса пользователя от oauth-провайдера;
- и, если этот пользователь зарегистрирован в системе – открывает ему доступ.
import re
from authomatic.adapters import WerkzeugAdapter
from flask import redirect, make_response
from flask.ext.login import login_user
from models import User
from app import app
EMAIL_REGEX = re.compile(r'[^@]+@[^@]+.[^@]+')
@app.route('/login/<provider_name>')
def login(provider_name):
# для работый с адаптером WerkzeugAdapter понадобится объект response
response = make_response()
try:
# перехватываем ошибки которые могут возникнуть при работе с oauth2 провайдером
# если result = None значит процедура логина находится в процессе выполнения
result = authomatic.login( WerkzeugAdapter( request, response ), provider_name )
if result:
# если получен результат oauth-логина
if result.user:
# и если имеется информация о пользователе
# получаем информацию о пользователе
result.user.update()
# получаем email
email = result.user.email
if email and EMAIL_REGEX.match(email):
# если указан правильный адрес
# находим соответствующего пользователя
user = User.query.filter_by( email = email ).first()
if user:
# если пользователь зарегистрирован с системе
# осуществляем вход в систему
login_user( user )
# делаем редирект на главную страницу сервиса
return redirect( url_for( 'index' ) )
# здесь отрабатываем все варианты отказа в регистрации
# ...
# ...
else:
# если результат oauth-логина еще не получен (result=None)
# возвращаем объект response
return response
Основаня часть взаимодействия с oauth-провайдером сводится к одной строке:
result = authomatic.login( WerkzeugAdapter( request, response ), provider_name )
при первоначальном заходе на адресу: authomatic.login
осуществляет редирект на указанного провайдера и передачу необходимых параметров;
затем провайдер делает обратный редирект по тому же адресу и authomatic.login
получает от провайдера требуемые данные.
Как видите совсем несложно. Основную часть времени занимает не программирование, а регистрация своего приложения в каждом из используемых провайдеров.
Автор: ValentynSolovyov