Web-строительское
Dec. 4th, 2007 09:40 pm![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
Пока тут народ радостно обсуждает наполеоновские планы строительства распределенной блог-системы
(1 2 3) я тем временем OpenID мучаю. Все-таки перловый код
brad писать умеет, а вот документацию хренушки.
Но с консьюмером я всё же уже разобрался. Может кому поможет
1. Пользователь приходит к нам на сайт и получает форму, в которую он вводит свой идентификатор.
Я немного развлекся и завел отдельное поле для юзернейма, отдельно менюшку для популятрных сайтов.
Можете в комменты накидать еще вариантов - впишу. Первый подход к снаряду (первый HTTP-запрос) завершен.
2.Пользователь жмет кнопку Log In, мы получаем (формируем из имени юзера и названия сайта) URL,
и делаем на неё HTTP-запрос. Парсим его, находим URL OpenID-продьюсера, которая там внутри как link rel написана. Это то, что называется claimed identity. (всё это кроме формирования URL делается единственным вызовом метода claimed_identity объекта Net::OpenID::Consumer. На данный момент никто еще не обещал что это правда.
Медодом check_url объекта Net::OpenID::ClaimedIdentity формируем URL-ку запроса на проверку. Не забываем указать куда возвращаться, добавив к URL нашего скрипт какой-нибудь параметр, чтобы, проанализировав его, мы узнали что это третий подход к снаряду, а не первый.
И радостно редиректим юзера на неё. Второй подход к снаряду завершен.
3. OpenID-продьюсер юзера о чем-то с юзерским браузером общается. Потом посылает юзера обратно к нам.
Мы проверяем, не попросили ли нас послать юзера что-то еще делать на том сайте - не передали ли нам
user_setup_url. Если передали, посылаем юзера туда. Когда он придет обратно, он, наверное будет на том сайте корректно залогинен. Если user_setup_url undefined, значит юзера больше мучить не нужно.
Проверяем, не отказался ли юзер от авторизации. Если отказался (метод user_cancel возвращает true) то увы и ах.
Иначе получаем объект Net::OpenId::VerifiedIdentity. Здесь мое терпение лопнуло, и я не стал писать в своем тестовом скрипте примеры извлечения оттуда foaf, rss и тому подобных вещей. Если этого объекта нам не дают,
значит что-то сломалось и нужно методом err вывести сообщение об ошибке. Если объект дали, то юзер успешно залогинен.
Вот текст скрипта, который в отличие от кода, имеющегося во встроенной документации модуля Net::OpenID::Consumer кладется на свой сайт и работает. Правда модулей ему нужна куча:
Net::OpenID::Consumer, LWP, Crypt::DH. Ну и CGI.pm, конечно, куда ж без нее, но она давн в дистрибутиве Perl.
(1 2 3) я тем временем OpenID мучаю. Все-таки перловый код
![[livejournal.com profile]](https://www.dreamwidth.org/img/external/lj-userinfo.gif)
Но с консьюмером я всё же уже разобрался. Может кому поможет
1. Пользователь приходит к нам на сайт и получает форму, в которую он вводит свой идентификатор.
Я немного развлекся и завел отдельное поле для юзернейма, отдельно менюшку для популятрных сайтов.
Можете в комменты накидать еще вариантов - впишу. Первый подход к снаряду (первый HTTP-запрос) завершен.
2.Пользователь жмет кнопку Log In, мы получаем (формируем из имени юзера и названия сайта) URL,
и делаем на неё HTTP-запрос. Парсим его, находим URL OpenID-продьюсера, которая там внутри как link rel написана. Это то, что называется claimed identity. (всё это кроме формирования URL делается единственным вызовом метода claimed_identity объекта Net::OpenID::Consumer. На данный момент никто еще не обещал что это правда.
Медодом check_url объекта Net::OpenID::ClaimedIdentity формируем URL-ку запроса на проверку. Не забываем указать куда возвращаться, добавив к URL нашего скрипт какой-нибудь параметр, чтобы, проанализировав его, мы узнали что это третий подход к снаряду, а не первый.
И радостно редиректим юзера на неё. Второй подход к снаряду завершен.
3. OpenID-продьюсер юзера о чем-то с юзерским браузером общается. Потом посылает юзера обратно к нам.
Мы проверяем, не попросили ли нас послать юзера что-то еще делать на том сайте - не передали ли нам
user_setup_url. Если передали, посылаем юзера туда. Когда он придет обратно, он, наверное будет на том сайте корректно залогинен. Если user_setup_url undefined, значит юзера больше мучить не нужно.
Проверяем, не отказался ли юзер от авторизации. Если отказался (метод user_cancel возвращает true) то увы и ах.
Иначе получаем объект Net::OpenId::VerifiedIdentity. Здесь мое терпение лопнуло, и я не стал писать в своем тестовом скрипте примеры извлечения оттуда foaf, rss и тому подобных вещей. Если этого объекта нам не дают,
значит что-то сломалось и нужно методом err вывести сообщение об ошибке. Если объект дали, то юзер успешно залогинен.
Вот текст скрипта, который в отличие от кода, имеющегося во встроенной документации модуля Net::OpenID::Consumer кладется на свой сайт и работает. Правда модулей ему нужна куча:
Net::OpenID::Consumer, LWP, Crypt::DH. Ну и CGI.pm, конечно, куда ж без нее, но она давн в дистрибутиве Perl.
#!/usr/bin/perl -T use strict; use warnings; use CGI; use LWP::UserAgent; use Net::OpenID::Consumer; my $cgi = new CGI; if ($cgi->param("user")) { my $csr = init_consumer($cgi); my $url; if ($cgi->param('site')) { $url = sprintf($cgi->param('site'),$cgi->param('user')); } else { $url = $cgi->param('user'); } print STDERR "URL entered: $url\n"; my $claimed_identity = $csr->claimed_identity($url); if (! defined $claimed_identity) { foreach my $par ($cgi->param) { print STDERR "$par = ".$cgi->param($par)."\n"; } die "No identity on given URL"; } my $check_url = $claimed_identity->check_url( return_to => $cgi->url(-full=>1,-query=>0)."?openidvfy=1", trust_root=>$cgi->url(-base=>1)); print $cgi->redirect(-location=> $check_url); } elsif ($cgi->param("openidvfy")) { my $csr = init_consumer($cgi); if (my $setup_url = $csr->user_setup_url) { print $cgi->redirect(-location=>$setup_url); exit(0); } elsif ($csr->user_cancel) { print $cgi->header('text/html'); print $cgi->start_html("Login cancelled"), $cgi->h1("Login cancelled"), $cgi->p("You've cancelled login on other site"), $cgi->end_html; } elsif (my $vident = $csr->verified_identity) { print $cgi->header('text/html'); print $cgi->start_html("Authentication successful"), $cgi->h1("Authentication successfull"), $cgi->p("You've successfully logged into our site as", $cgi->a({-href=>$vident->url},$vident->display),". Congratulations!"), $cgi->end_html; } else { print $cgi->header('text/html'); print $cgi->start_html("Authentication failed"), $cgi->h1("Authentication failed"), $cgi->p("Error validating identity:", $cgi->escapeHTML($csr->err)); $cgi->end_html; } } else { # Print out form to enter OpenID URL my %site_list=( 'http://users.livejournal.com/%s'=>'LiveJournal', 'http://lj.rossia.org/users/%s'=>'LJ.Rossia.org', 'http://www.greatestjournal.com/users/%s'=>'GreatestJournal', '%s','Other (enter full URL into Login field'); print $cgi->header("text/html"), $cgi->start_html("My test open_id page"), $cgi->h1("My test open_id page"), $cgi->start_form(-method=>'POST'), "Login:",$cgi->textfield(-name=>"user",-size=>40),"<br>", "Site:", $cgi->popup_menu(-name=>"site",-Values=>[sort keys(%site_list)], -labels=>\%site_list), "<br>",$cgi->submit(-name=>'login',-value=>'Log in'), $cgi->end_form, $cgi->end_html; exit(0); } sub init_consumer { my $cgi=shift; return Net::OpenID::Consumer->new( ua => LWP::UserAgent->new(), args => $cgi, consumer_secret => 'sdf@!#$AGSADG', required_root => $cgi->url(-base=>1), ); }