Pergunta

Recentemente, comecei a escrever minhas próprias PHP OpenID consumidor de classe a fim de entender melhor openID.Como um guia, eu estive fazendo referência a [LightOpenID Classe][1].Para a maior parte, eu entendo o código e como OpenID obras.A minha confusão vem ao olhar do autor discover função:

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

Ok, Aqui está a lógica de como eu a entendo (basicamente):

  1. Verifique para ver se o $url envia um válido XRDS arquivo que você, em seguida, analisar para descobrir o OpenID do provedor de ponto de extremidade.
    • No meu entendimento, este é chamado de o Yadis método de autenticação.
  2. Se não XRDS arquivo é encontrado, Verifique o corpo da resposta para um HTML <link> tag que contém o url do ponto de extremidade.

O que.A.Heck.

Quero dizer a sério?Essencialmente tela raspar a resposta e espero que você encontre um link com o atributo adequado valor?

Agora, não me leve a mal, essa classe funciona como um encanto, e é incrível.Eu só estou falhando grok os dois métodos distintos usados para descobrir o ponto de extremidade:XRDS (yadis) e HTML.

Minhas Perguntas

  1. Estes são apenas dois métodos utilizados no processo de descoberta?
  2. É só usado na versão 1.1 do OpenID e o outro na versão 2?
  3. É essencial para apoiar os dois métodos?
  4. O site que eu encontrei o HTML método é de Yahoo.Eles são porcas?

Obrigado novamente por sua vez, pessoal.Peço desculpas se eu som um pouco espantado, mas eu estava realmente espantado com a metodologia, uma vez que eu comecei a entender que medidas estavam sendo tomadas para encontrar o ponto de extremidade.

Foi útil?

Solução

Especificação é seu amigo.

Mas respondendo a sua pergunta:

  1. Sim.Esses são apenas dois métodos definidos pelo OpenID especificações (pelo menos, para URLs, há um terceiro método para XRIs).
  2. Não, tanto pode ser usado com a versão do protocolo.Leia a função cuidadosamente e você verá que ele suporta ambos os métodos para ambas as versões.
  3. Se você deseja que sua biblioteca para trabalhar com cada fornecedor e usuário, é melhor você fazer.Alguns usuários cole o código HTML tags em seus sites, de modo que seus url do site pode ser usado como um openid.
  4. Alguns provedores mesmo usar os dois métodos ao mesmo tempo, para manter a compatibilidade com os consumidores ao não implementar YADIS descoberta (que não faz parte do OpenID 1.1, mas pode ser usado com ele).De modo que faz sentido.

E sim, HTML descoberta é sobre como procurar um <link> no corpo da resposta.Que por isso é chamado de HTML descoberta.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top