vitus_wagner: My photo 2005 (Default)
[personal profile] vitus_wagner
Пока тут народ радостно обсуждает наполеоновские планы строительства распределенной блог-системы
(1 2 3) я тем временем OpenID мучаю. Все-таки перловый код [livejournal.com profile] 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.

#!/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),
	 );
}	 



This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

Profile

vitus_wagner: My photo 2005 (Default)
vitus_wagner

June 2025

S M T W T F S
1234567
891011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 2nd, 2025 12:31 am
Powered by Dreamwidth Studios