Gần đây, tôi đã bắt đầu viết lớp người tiêu dùng OpenID PHP của riêng mình để hiểu rõ hơn về OpenID. Là một hướng dẫn, tôi đã tham khảo [LightOpenID Class] [1]. Đối với hầu hết các phần, tôi hiểu mã và cách OpenID hoạt động. sự nhầm lẫn của tôi đến khi nhìn vào discover
chức năng của tác giả:OpenID Discovery Methods - Yadis VS HTML
function discover($url)
{
if(!$url) throw new ErrorException('No identity supplied.');
# We save the original url in case of Yadis discovery failure.
# It can happen when we'll be lead to an XRDS document
# which does not have any OpenID2 services.
$originalUrl = $url;
# A flag to disable yadis discovery in case of failure in headers.
$yadis = true;
# We'll jump a maximum of 5 times, to avoid endless redirections.
for($i = 0; $i < 5; $i ++) {
if($yadis) {
$headers = explode("\n",$this->request($url, 'HEAD'));
$next = false;
foreach($headers as $header) {
if(preg_match('#X-XRDS-Location\s*:\s*(.*)#', $header, $m)) {
$url = $this->build_url(parse_url($url), parse_url(trim($m[1])));
$next = true;
}
if(preg_match('#Content-Type\s*:\s*application/xrds\+xml#i', $header)) {
# Found an XRDS document, now let's find the server, and optionally delegate.
$content = $this->request($url, 'GET');
# OpenID 2
# We ignore it for MyOpenID, as it breaks sreg if using OpenID 2.0
$ns = preg_quote('http://specs.openid.net/auth/2.0/');
if (preg_match('#<Service.*?>(.*)<Type>\s*'.$ns.'(.*?)\s*</Type>(.*)</Service>#s', $content, $m)
&& !preg_match('/myopenid\.com/i', $this->identity)) {
$content = $m[1] . $m[3];
if($m[2] == 'server') $this->identifier_select = true;
$content = preg_match('#<URI>(.*)</URI>#', $content, $server);
$content = preg_match('#<LocalID>(.*)</LocalID>#', $content, $delegate);
if(empty($server)) {
return false;
}
# Does the server advertise support for either AX or SREG?
$this->ax = preg_match('#<Type>http://openid.net/srv/ax/1.0</Type>#', $content);
$this->sreg = preg_match('#<Type>http://openid.net/sreg/1.0</Type>#', $content);
$server = $server[1];
if(isset($delegate[1])) $this->identity = $delegate[1];
$this->version = 2;
$this->server = $server;
return $server;
}
# OpenID 1.1
$ns = preg_quote('http://openid.net/signon/1.1');
if(preg_match('#<Service.*?>(.*)<Type>\s*'.$ns.'\s*</Type>(.*)</Service>#s', $content, $m)) {
$content = $m[1] . $m[2];
$content = preg_match('#<URI>(.*)</URI>#', $content, $server);
$content = preg_match('#<.*?Delegate>(.*)</.*?Delegate>#', $content, $delegate);
if(empty($server)) {
return false;
}
# AX can be used only with OpenID 2.0, so checking only SREG
$this->sreg = preg_match('#<Type>http://openid.net/sreg/1.0</Type>#', $content);
$server = $server[1];
if(isset($delegate[1])) $this->identity = $delegate[1];
$this->version = 1;
$this->server = $server;
return $server;
}
$next = true;
$yadis = false;
$url = $originalUrl;
$content = null;
break;
}
}
if($next) continue;
# There are no relevant information in headers, so we search the body.
$content = $this->request($url, 'GET');
if($location = $this->htmlTag($content, 'meta', 'http-equiv', 'X-XRDS-Location', 'value')) {
$url = $this->build_url(parse_url($url), parse_url($location));
continue;
}
}
if(!$content) $content = $this->request($url, 'GET');
# At this point, the YADIS Discovery has failed, so we'll switch
# to openid2 HTML discovery, then fallback to openid 1.1 discovery.
$server = $this->htmlTag($content, 'link', 'rel', 'openid2.provider', 'href');
$delegate = $this->htmlTag($content, 'link', 'rel', 'openid2.local_id', 'href');
$this->version = 2;
# Another hack for myopenid.com...
if(preg_match('/myopenid\.com/i', $server)) {
$server = null;
}
if(!$server) {
# The same with openid 1.1
$server = $this->htmlTag($content, 'link', 'rel', 'openid.server', 'href');
$delegate = $this->htmlTag($content, 'link', 'rel', 'openid.delegate', 'href');
$this->version = 1;
}
if($server) {
# We found an OpenID2 OP Endpoint
if($delegate) {
# We have also found an OP-Local ID.
$this->identity = $delegate;
}
$this->server = $server;
return $server;
}
throw new ErrorException('No servers found!');
}
throw new ErrorException('Endless redirection!');
}
[1]: http://gitorious.org/lightopenid
Được rồi, đây là logic như tôi hiểu nó (về cơ bản):
- Hãy kiểm tra để xem nếu
$url
gửi cho bạn một tập tin XRDS hợp lệ mà sau đó bạn phân tích cú pháp để tìm ra điểm cuối của nhà cung cấp OpenID.- Từ hiểu biết của tôi, điều này được gọi là phương thức xác thực Yadis.
- Nếu không có tập tin XRDS được tìm thấy, Kiểm tra cơ thể của phản ứng cho một HTML < liên kết > thẻ có chứa url của endpoint.
Điều gì. Các. Heck.
Ý tôi là nghiêm túc? Về cơ bản, màn hình loại bỏ phản hồi và hy vọng bạn tìm thấy một liên kết có giá trị thuộc tính thích hợp?
Bây giờ, đừng hiểu lầm tôi, lớp học này hoạt động như một sự quyến rũ và nó thật tuyệt vời. Tôi chỉ không mò mẫm hai phương pháp riêng biệt được sử dụng để khám phá điểm cuối: XRDS (yadis) và HTML.
Câu hỏi của tôi
- Là những hai phương pháp chỉ được sử dụng trong quá trình khám phá?
- Có phải chỉ được sử dụng trong phiên bản 1.1 của OpenID và phiên bản khác trong phiên bản 2 không?
- Điều quan trọng là hỗ trợ cả hai phương pháp?
- Trang web tôi đã gặp phải là phương pháp HTML là Yahoo. Họ có hạt không?
Xin cảm ơn một lần nữa cho mọi người. Tôi xin lỗi nếu tôi có vẻ hơi kinh ngạc, nhưng tôi đã thực sự choáng váng trước phương pháp khi tôi bắt đầu hiểu những biện pháp đã được thực hiện để tìm ra điểm cuối cùng.
Thông tin tuyệt vời, giải thích rất hữu ích. Cảm ơn bạn đã dành thời gian để giải quyết sự nhầm lẫn/thất vọng của tôi. 1 và câu trả lời để khởi động. –