Я обещал писать бекенды для django-registration, но оказалось существует замечательное приложение для всевозможных видов аутентификации с последующим созданием пользователя и авторизации.
* OpenID - yandex.ru, rambler.ru, yahoo.ru, google.com
* OAuth - twitter.com
* OpenAPI - Вконтакте.ру
* FacebookConnect - facebook.com
Устанавливаем:
c:\Python26\Scripts\pip.exe install hg+http://bitbucket.org/offline/django-p
ublicauth@7371e8f71be1#egg=django-publicauth
Прописываем в requirements.txt.
Добавляем 'publicauth' в INSTALLED_APPS. Добавляем 'annoying.middlewares.RedirectMiddleware' в MIDDLEWARE_CLASSES.
Добавим 'publicauth.PublicBackend' в AUTHENTICATION_BACKENDS.
Запускаем syncdb.
OpenID
Необходимо установить python-openid (2.2.5).
Добавим
(r'', include('publicauth.urls')),
в файл /users/urls.py , тем самым переопределив url login и logout приложения нашими url'ами, и оставив остальные, необходимые для работы приложения. Ознакомимся с содержимым темплейта login.html, и добавим следующую форму в наш login.html:
Создадим директорию publicauth в users/templates/ , скопируем туда содержимое и поправим под наш сайт.
Также в файле users/forms.py создадим форму ExtraForm (форма для заполнения дополнительных полей после сторонней аутентификации, например имя пользователя).
Подсмотреть можно здесь.
PUBLICAUTH_EXTRA_FORM = "users.forms.ExtraForm"
Пробуем логиниться.
Приложение требует установленного и настроенного messages framework, как указано в документации (для самостоятельного рассмотрения) для вывода сообщений. У меня уже оно почти настроено (сообщение при сохранении профиля реализованно как раз через него).
Сообщения к сожалению не переведены, придется сделать это самим.
Создадим файл src/djutils/locale/ru_RU/LC_MESSAGES/django.po и переведем файл.
msgid "To complete registration, check your email and activate your account"
msgstr "Для завершения регистрации проверьте e-mail и активируйте учетную запись"
msgid "We are sorry, but registration is disabled. Come back later"
msgstr "Извините, но регистрация закрыта"
msgid "Please fill openid url field"
msgstr "Пожалуйста, заполните поле openid"
msgid "Your authentication provider returned bad response, please try again"
msgstr "Ваш провайдер аутентификации вернул влохой ответ, попробуйте еще раз"
msgid "You have cancelled OpenID authentication"
msgstr "Вы отменили аутентификацию по OpenID"
msgid "OpenID authentication failed. Reason: %s"
msgstr "Аутентификация OpenID провалилась. Причина: %s"
msgid "You have successfully logged out"
msgstr "Вы успешно вышли"
msgid "Your existing account was merged with new authentication account"
msgstr "Существующая учетная запись была объединена с новой учетной записью"
msgid "Your account is not activated. Please activate it first."
msgstr "Ваша учетная запись не активирована. Пожалуйста, активируйте ее сначала."
msgid "You have successfully authenticated"
msgstr "Вы успешно аутентифицированны"
msgid "Invalid response received from facebook server, please start the authentication process again"
msgstr "Неверный ответ от сервера facebook, пожалуйста запустите процесс аутентификации еще раз"
msgid "Invalid response received from OpenID server, please start the authentication process again"
msgstr "Неверный ответ от сервера OpenID, пожалуйста запустите процесс аутентификации еще раз"
msgid "Invalid response received from vkontakte server, please start the authentication process again"
msgstr "Неверный ответ от сервера vkontakte, пожалуйста запустите процесс аутентификации еще раз"
Скомпилируем (запуск в директории src\apps\djutils\)
>python C:\Python26\Lib\site-packages\django\bin\django-admin.py compilemessages.
Добавим 'django.middleware.locale.LocaleMiddleware', в MIDDLEWARE_CLASSES.
ВКонтакте
Делаем все как по ссылке на хабр. Единственно, я не понял для чего нужно VKONTAKTE_API_KEY, работает и без него, да и в бекенде vkontakte.py он не используется.
Делаем по мануалу, ссылка на документацию на facebook.
В настройки надо добавить
FACEBOOK_PROFILE_MAPPING={ 'name': 'username', }
OAuth (Twitter)
Install python-oauth:
>pip.exe install oauth
Настройки:
TWITTER_CONSUMER_KEY = "key"
TWITTER_CONSUMER_SECRET = "secret"
TWITTER_REQUEST_TOKEN_URL = "https://twitter.com/oauth/request_token"
TWITTER_ACCESS_TOKEN_URL = "https://twitter.com/oauth/access_token"
TWITTER_AUTHORIZE_URL = "https://twitter.com/oauth/authorize"
TWITTER_API_URL = "http://twitter.com/users/show.json?user_id=%s"
TWITTER_PROFILE_MAPPING = { 'screen_name': 'username', }
Темплейт:
В итоге, в url auth_login мы должны иметь авторизацию на сайте или аутентификацию в сторонних сайтах в случае неавторизированного пользователя, а также аутентификацию в сторонних сайтах и сопоставления этих профилей с текущим профилем. И, естественно, логин любым из методов для существующего пользователя.
Как обычно, запускаем тесты, мержим транк, делаем развертывание, и сравниваем musicmans.ru.
ps. По поводу тестов. Да все уже написано:
http://djangotesting.com/
http://habrahabr.ru/blogs/django/91471/
http://pyobject.ru/blog/2009/09/13/django-external-test-tools/
http://night-fairy-tales.com/2009/10/django-eclipse.html
Разбираемся, пишем (На данный момент нами написано лишь редактирование профиля в приложении users, вот для него и можно написать тесты).
pps. Насткнулся на баг в тестах django-registration.
Вот решение (developmet.py)
TEST = False
manage_command = filter(lambda x: x.find('manage.py') != -1, sys.argv)
if len(manage_command) != 0:
command = sys.argv.index(manage_command[0]) + 1
if command < len(sys.argv):
TEST = sys.argv[command] == "test"
if TEST:
LANGUAGE_CODE = 'en-us'
Слежу за статьями на этом блоге внимательно.
ОтветитьУдалитьХочется выразить огромную благодарность за действительно хорошие статьи по Django!
Спасибо.
Пожалуйста. :)
ОтветитьУдалитьСтатьи не профессиональные, стараюсь просто осветить максимум информации за минимум строк.
Во спасибо, недавно искал инфу как OpenID прицепить к django, так и не нашел. Vermus, спасибо!
ОтветитьУдалитьFaceBook что-то не пишет куки по-нормальному. Разбираюсь пока.
ОтветитьУдалитьЗдравствуйте! Пытаемся сделать авторизацию на нашем проекте. Есть небольшие трудности.
ОтветитьУдалитьVK.init({ apiId: 1922709, nameTransportPath: '/my-xdreceiver.html' });
function vk_login() {
VK.Auth.login(function(response) {
if (response.session == "connected") {
window.location = "/complete/vkontakte/"
}
});
return false;
};
разместил такой код, openapi загружаю с vkontakte. Если авторизируюсь то до редиректа дело не доходит. Если уже авторизован то выдает ошибку Recv err: TypeError: Cannot convert 'VK.XDM.remote' to object
Пожалуйста, помогите решить проблему.
Судя по коду все правильно. Я создавал приложение типа веб-сайт.
ОтветитьУдалитьps. спасибо за сообщения, обнаружилась ошибка в notification.send, ругается на кодировку.
Ага, проблема была в локали. Но хостинге по умолчанию не определена локаль.
ОтветитьУдалитьПосему правим wsgi.py:
import locale
def force_utf8_hack():
reload(sys)
sys.setdefaultencoding('utf-8')
for attr in dir(locale):
if attr[0:3] != 'LC_':
continue
aref = getattr(locale, attr)
locale.setlocale(aref, '')
(lang, enc) = locale.getlocale(aref)
if lang != None:
try:
locale.setlocale(aref, (lang, 'UTF-8'))
except:
os.environ[attr] = lang + '.UTF-8'
force_utf8_hack()
application = django.core.handlers.wsgi.WSGIHandler()
Добрый день!
ОтветитьУдалитьДелаем авторизацию на сайте, проблема в том, что нам нужно чтобы она проходила через AJAX, то есть без редиректов. Как изменить код под AJAX?