Domanda

Di recente, ho iniziato a scrivere la mia classe di consumo OpenID PHP per capire meglio l'OpenID. Come guida, mi riferisco alla [classe Lightopenid] [1]. Per la maggior parte, capisco il codice e come funziona OpenID. La mia confusione arriva quando si guarda la funzione discover dell'autore:

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
.

Okay, ecco la logica come lo capisco (fondamentalmente):

    .
  1. Verifica se il $url ti invia un file XRDS valido che quindi analizza per capire l'endpoint del provider OpenID.
      .
    • Dalla mia comprensione, questo è chiamato il metodo di autenticazione Yadis.
  2. Se non viene trovato alcun file XRDS, controlla il corpo della risposta per un tag HTML che contiene l'URL dell'endpoint .
  3. Cosa. Il. Diamine.

    Voglio dire seriamente? Essenzialmente la schermatura Raschiare la risposta e spero che trovi un collegamento con il valore dell'attributo appropriato?

    Ora, non farmi torto, questa classe funziona come un fascino ed è fantastico. Sto solo non riuscire a Grok i due metodi separati utilizzati per scoprire l'endpoint: XRDS (Yadis) e HTML.

    Le mie domande

      .
    1. sono quelli che gli unici due metodi utilizzati nel processo di scoperta?
    2. è solo utilizzato nella versione 1.1 di OpenID e l'altro nella versione 2?
    3. è fondamentale supportare entrambi i metodi?
    4. Il sito che ho riscontrato il metodo HTML è Yahoo. Sono pazzi?
    5. Grazie ancora per il tuo tempo folks. Mi scuso se sembro un po 'sbloccato, ma ero sinceramente stordito dalla metodologia una volta che ho iniziato a capire quali misure venivano prese per trovare l'endpoint.

È stato utile?

Soluzione

Specifica è il tuo amico.

Ma rispondere alla tua domanda:

    .
  1. sì. Questi sono gli unici due metodi definiti dalle specifiche openid (almeno, per gli URL - c'è un terzo metodo per XRIS).
  2. No, entrambi possono essere utilizzati con entrambe le versioni del protocollo. Leggi attentamente la funzione e vedrai che supporta entrambi i metodi per entrambe le versioni.
  3. Se vuoi che la tua libreria funzioni con ogni fornitore e utente, faresti meglio a farlo. Alcuni utenti incollano i tag HTML nei loro siti, quindi l'URL del loro sito può essere utilizzato come OpenID.
  4. Alcuni provider usano anche entrambi i metodi contemporaneamente, al mantenimento della compatibilità con i consumatori che non implementano la scoperta di Yadis (che non fa parte di OpenID 1.1, ma può essere usato con esso). Quindi ha senso.
  5. E sì, la scoperta HTML riguarda la ricerca di un <link> nel corpo di risposta. Ecco perché si chiama HTML Discovery.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top