Pregunta

Recientemente, he comenzado a escribir mi propia PHP OpenID clase de consumidor con el fin de comprender mejor openID.Como una guía, he estado hace referencia a la [LightOpenID Clase][1].Para la mayor parte, entiendo el código y cómo OpenID obras.Mi confusión se presenta cuando se busca al autor del discover función:

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

Bueno, Aquí está la lógica como yo lo entiendo (básicamente):

  1. Revise para ver si el $url envía un válido XRDS archivo que usted, a continuación, analizar averiguar el OpenID del proveedor de la estación.
    • Desde mi entender, esto se llama el Yadis método de autenticación.
  2. Si no XRDS se encuentra el archivo, Compruebe el cuerpo de la respuesta para un HTML <link> la etiqueta que contiene la dirección url del extremo.

Qué.El.Diablos.

Lo digo en serio?Esencialmente raspar la pantalla la respuesta y la esperanza de encontrar un vínculo con el correspondiente valor de atributo?

Ahora, no me malinterpreten, esta clase funciona como un encanto y es impresionante.Sólo estoy fallando para asimilar los dos métodos que se utilizan para descubrir el punto final:XRDS (yadis) y HTML.

Mis Preguntas

  1. Son esos los únicos dos métodos utilizados en el proceso de descubrimiento?
  2. Es uno sólo se utiliza en la versión 1.1 de OpenID y el otro en la versión 2?
  3. Es crítico para apoyar ambos métodos?
  4. El sitio me he encontrado con el HTML método es Yahoo.Son los frutos secos?

Gracias de nuevo por su tiempo gente.Pido disculpas si sueno un poco asombrado, pero yo estaba realmente sorprendido por la metodología una vez que empecé a entender qué medidas se habían tomado para encontrar la estación.

¿Fue útil?

Solución

Especificación es tu amigo.

Pero respondiendo a tu pregunta:

  1. Sí.Esos son los únicos dos métodos definidos por el OpenID especificaciones (al menos, para las direcciones Url-existe un tercer método para XRIs).
  2. No, ambos pueden usarse tanto con la versión del protocolo.Lea la función de cuidado, y verás que es compatible con ambos métodos para ambas versiones.
  3. Si usted quiere que su biblioteca para trabajar con cada proveedor y el usuario, es mejor que hacer.Algunos usuarios de pegar las etiquetas HTML en sus sitios, por lo que su url del sitio puede ser utilizado como un openid.
  4. Algunos proveedores incluso el uso de ambos métodos a la vez, para mantener la compatibilidad con los consumidores no aplicación de YADIS descubrimiento (que no es parte de OpenID 1.1, pero puede ser usado con él).Así que tiene sentido.

Y sí, HTML descubrimiento es sobre la búsqueda de un <link> en el cuerpo de la respuesta.Es por eso que se llama HTML descubrimiento.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top