2010-07-16 33 views
6

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):

  1. 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.
  2. 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

  1. Là những hai phương pháp chỉ được sử dụng trong quá trình khám phá?
  2. 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?
  3. Điều quan trọng là hỗ trợ cả hai phương pháp?
  4. 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.

Trả lời

5

Specification là bạn của bạn.

Nhưng trả lời câu hỏi của bạn:

  1. Yes. Đó là hai phương thức duy nhất được xác định bởi các đặc tả OpenID (ít nhất, đối với các URL - có một phương thức thứ ba cho các XRI).
  2. Không, cả hai có thể được sử dụng với cả hai phiên bản của giao thức. Đọc kỹ chức năng này, và bạn sẽ thấy nó hỗ trợ cả hai phương thức cho cả hai phiên bản.
  3. Nếu bạn muốn thư viện của mình hoạt động với mọi nhà cung cấp và người dùng, bạn nên làm. Một số người dùng dán các thẻ HTML vào các trang web của họ, vì vậy url của trang web của họ có thể được sử dụng như một openid.
  4. Một số nhà cung cấp thậm chí sử dụng cả hai phương pháp cùng một lúc, để tương thích với người tiêu dùng không thực hiện phát hiện YADIS (không phải là một phần của OpenID 1.1, nhưng có thể được sử dụng với nó). Vì vậy, điều đó có ý nghĩa.

Và có, khám phá HTML là tìm kiếm một số <link> trong phần phản hồi. Đó là lý do tại sao nó được gọi là khám phá HTML.

+0

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. –