http://habrahabr.ru/company/theonlypage/blog/239189/
Практически любое веб-приложение предоставляет возможность авторизации пользователя с использованием учетной записи пользователя, в каком либо из известных социальных сервисов.
Магия авторизации происходит строго по протоколу 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/linkedinwww.theonlypage.com/login/microsoft
Также на страничке регистрации приложения у провайдера, нам надо получить
код пользователя и
секретный ключ, в терминах различных провайдеров они соответственно называются:
|
код пользователя |
секретный ключ |
---|
Facebook |
App ID |
App Secret |
Google |
Client ID |
Client secret |
LinkedIn |
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
получает от провайдера требуемые данные.
Как видите совсем несложно. Основную часть времени занимает не программирование, а регистрация своего приложения в каждом из используемых провайдеров.