2010-07-16 2 views
6

최근 openID를 더 잘 이해하기 위해 PHP OpenID 소비자 클래스를 작성하기 시작했습니다. 안내서로서, 저는 [LightOpenID Class] [1]을 참조했습니다. 대부분의 경우 코드와 OpenID의 작동 방식을 이해합니다.OpenID 디스커버리 방법 - 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 

좋아 내가 (기본적으로) 그것을 이해, 여기에 논리는 다음과 같습니다 : 저자의 discover 기능을 볼 때 내 혼란이 오는 $url 당신에게 유효한 XRDS 파일을 보내는 경우

  1. 점검보고 그 그런 다음 구문 분석하여 OpenID 공급자의 끝점을 파악합니다.
    • 제 생각에 Yadis 인증 방법이라고합니다. 더 XRDS 파일이 발견되지 않는 경우
  2. 가있는 HTML < 링크 엔드 포인트의 URL을 포함 > 태그 응답의 몸을 확인 .

무엇을? 그만큼. 지옥.

나는 심각하게 의미합니까? 본질적으로 화면이 응답을 긁어 내고 적절한 속성 값을 가진 링크를 찾았 으면 좋겠습니까?

지금은 잘못하지 마세요,이 수업은 매력처럼 작동하며 멋지 네요. 나는 XRDS (yadis)와 HTML이라는 두 종단점을 발견하는 데 사용 된 두 가지 방법을 모르고있다.

내 질문

  1. 는 사람들은 검색 프로세스에 사용되는 두 가지 방법이 있습니까?
  2. OpenID 버전 1.1과 버전 2에서만 사용됩니까?
  3. 두 가지 방법을 모두 지원하는 것이 중요합니까?
  4. 내가 HTML 메소드를 접한 사이트는 야후입니다. 견과류입니까?

시간을내어 다시 한번 감사드립니다. 조금 놀랐다면 사과드립니다.하지만 일단 endPoint를 찾기 위해 어떤 조치가 취해지고 있는지 이해하기 시작하면 방법론에 정말로 놀랐습니다.

답변

5

Specification은 (는) 친구입니다.

하지만 당신의 질문에 대답 :

  1. 예. 이것들은 OpenID 사양에 의해 정의 된 유일한 두 가지 방법입니다 (최소한 URL의 경우 XRI의 세 번째 방법이 있습니다).
  2. 아니요, 둘 다 프로토콜 버전과 함께 사용할 수 있습니다. 이 함수를 자세히 읽으면 두 버전 모두에서 두 가지 방법을 모두 지원한다는 것을 알 수 있습니다.
  3. 라이브러리를 모든 제공 업체 및 사용자와 함께 사용하려는 경우 더 잘 수행 할 수 있습니다. 일부 사용자는 HTML 태그를 사이트에 붙여 넣기 때문에 사이트의 URL을 openid로 사용할 수 있습니다.
  4. 일부 공급자는 YADIS 검색을 구현하지 않는 소비자 (OpenID 1.1의 일부가 아니지만 함께 사용할 수 있음)와의 호환성을 유지하기 위해 두 가지 방법을 동시에 사용합니다. 그래서 그것은 의미가 있습니다.

예, HTML 검색은 응답 본문에서 <link>을 검색하는 것입니다. 이것이 HTML 발견이라고 불리는 이유입니다.

+0

우수한 정보, 매우 유용한 설명. 저의 혼란/좌절감을 해결해 주셔서 감사합니다. +1 및 부팅 응답. –