开发者

Has any one got class.openid.php working with google openID?

I am trying to study class.openid.php because it is simpler and smaller than

lightopenid. for my purposes 200 lines do matter. But class.openid.php does not work with google openID https://www.google.com/accounts/o8/id, prints to me such error:

ERROR CODE: OPENID_NOSERVERSFOUND
ERROR DESCRIPTION: Cannot find OpenID Server TAG on Identity page.

is it possible to make class.openid.php (any version) work with google openID and how to do such thing?

class.openid.php can be taken here but it did not worked for me out of the box so I had to find all <? and replace tham with <?php in case someone would like to see code I've got:

html interface page:

<?php
require('class.openid.v3.php');

if ($_POST['openid_action'] == "login"){ // Get identity from user and redirect browser to OpenID Server
    $openid = new SimpleOpenID;
    $openid->SetIdentity($_POST['openid_url']);
    $openid->SetTrustRoot('http://' . $_SERVER["HTTP_HOST"]);
    $openid->SetRequiredFields(array('email','fullname'));
    $openid->SetOptionalFields(array('dob','gender','postcode','country','language','timezone'));
    if ($openid->GetOpenIDServer()){
        $openid->SetApprovedURL('http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PATH_INFO"]);     // Send Response from OpenID server to this script
        $openid->Redirect();    // This will redirect user to OpenID Server
    }else{
        $error = $openid->GetError();
        echo "ERROR CODE: " . $error['code'] . "<br>";
        echo "ERROR DESCRIPTION: " . $error['description'] . "<br>";
    }
    exit;
}
else if($_GET['openid_mode'] == 'id_res'){  // Perform HTTP Request to OpenID server to validate key
    $openid = new SimpleOpenID;
    $openid->SetIdentity($_GET['openid_identity']);
    $openid_validation_result = $openid->ValidateWithServer();
    if ($openid_validation_result == true){         // OK HERE KEY IS VALID
        echo "VALID";
    }else if($openid->IsError() == true){           // ON THE WAY, WE GOT SOME ERROR
        $error = $openid->GetError();
        echo "ERROR CODE: " . $error['code'] . "<br>";
        echo "ERROR DESCRIPTION: " . $error['description'] . "<br>";
    }else{                                          // Signature Verification Failed
        echo "INVALID AUTHORIZATION";
    }
}else if ($_GET['openid_mode'] == 'cancel'){ // User Canceled your Request
    echo "USER CANCELED REQUEST";
}
?>
<html>
<head>
    <title>OpenID Example</title>
</head>
<body>
<div>
<fieldset id="openid">
<legend>OpenID Login</legend>
<form action="<?php echo 'http://' . $_SERVER["HTTP_HOST"] . $_SERVER["PATH_INFO"]; ?>" method="post" onsubmit="this.login.disabled=true;">
<input type="hidden" name="openid_action" value="login">
<div><input type="text" name="openid_url" class="openid_login"><input type="submit" name="login" value="login &gt;&gt;"></div>
<div><a href="http://www.myopenid.com/" class="link" >Get an OpenID</a></div>
</form>
</fieldset>
</div>
<div style="margin-top: 2em; font-family: arial; font-size: 0.8em; border-top:1px solid gray; padding: 4px;">Sponsored by: <a href="http://www.fivestores.com">FiveStores</a> - get your free online store; includes extensive API for developers; <i style="color: gray;">integrated with  <a href="http://en.wikipedia.org/wiki/OpenID">OpenID</a></i></div>
</body>
</html>

and php class

<?php
/*
    FREE TO USE Under License: GPLv3
    Simple OpenID PHP Class 
    Some modifications by Eddie Roosenmaallen, eddie@roosenmaallen.com
*/

class SimpleOpenID{
    var $openid_url_identity;
    var $URLs = array();
    var $error = array();
    var $fields = array(
        'required'   => array(),
        'optional'   => array(),
    );

    function SimpleOpenID(){
        if (!function_exists('curl_exec')) {
            die('Error: Class SimpleOpenID requires curl extension to work');
        }
    }

    function SetOpenIDServer($a){
        $this->URLs['openid_server'] = $a;
    }

    function SetTrustRoot($a){
        $this->URLs['trust_root'] = $a;
    }

    function SetCancelURL($a){
        $this->URLs['cancel'] = $a;
    }

    function SetApprovedURL($a){
        $this->URLs['approved'] = $a;
    }

    function SetRequiredFields($a){
        if (is_array($a)){
            $this->fields['required'] = $a;
        }else{
            $this->fields['required'][] = $a;
        }
    }

    function SetOptionalFields($a){
        if (is_array($a)){
            $this->fields['optional'] = $a;
        }else{
            $this->fields['optional'][] = $a;
        }
    }

    function SetIdentity($a){   // Set Identity URL
            if ((stripos($a, 'http://') === false)
               && (stripos($a, 'https://') === false)){
                $a = 'http://'.$a;
            }
            $this->openid_url_identity = $a;
    }

    function GetIdentity(){     // Get Identity
        return $this->openid_url_identity;
    }

    function GetError(){
        $e = $this->error;
        return array('code'=>$e[0],'description'=>$e[1]);
    }

    function ErrorStore($code, $desc = null){
        $errs['OPENID_NOSERVERSFOUND'] = 'Cannot find OpenID Server TAG on Identity page.';
        if ($desc == null){
            $desc = $errs[$code];
        }
        $this->error = array($code,$desc);
    }

    function IsError(){
        if (count($this->error) > 0){
            return true;
        }else{
            return false;
        }
    }

    function splitResponse($response) {
        $r = array();
        $response = explode("\n", $response);
        foreach($response as $line) {
            $line = trim($line);
            if ($line != "") {
                list($key, $value) = explode(":", $line, 2);
                $r[trim($key)] = trim($value);
            }
        }
        return $r;
    }

    function OpenID_Standarize($openid_identity = null){
        if ($openid_identity === null)
            $openid_identity = $this->openid_url_identity;

        $u = parse_url(strtolower(trim($openid_identity)));

        if (!isset($u['path']) || ($u['path'] == '/')) {
            $u['path'] = '';
        }
        if(substr($u['path'],-1,1) == '/'){
            $u['path'] = substr($u['path'], 0, strlen($u['path'])-1);
        }
        if (isset($u['query'])){ // If there is a query string, then use identity as is
            return $u['host'] . $u['path'] . '?' . $u['query'];
        }else{
            return $u['host'] . $u['path'];
        }
    }

    function array2url($arr){ // converts associated array to URL Query String
        if (!is_array($arr)){
            return false;
        }
        $query = '';
        foreach($arr as $key => $value){
            $query .= $key . "=" . $value . "&";
        }
        return $query;
    }

    function CURL_Request($url, $method="GET", $params = "") { // Remember, SSL MUST BE SUPPORTED
            if (is_array($params)) $params = $this->array2url($params);
            $curl = curl_init($url . ($method == "GET" && $params != "" ? "?" . $params : ""));
            curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
            curl_setopt($curl, CURLOPT_HEADER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_HTTPGET, ($method == "GET"));
            curl_setopt($curl, CURLOPT_POST, ($method == "POST"));
            if ($method == "POST") curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
            $response = curl_exec($curl);

            if (curl_errno($curl) == 0){
                $response;
            }else{
                $this->ErrorStore('OPENID_CURL', curl_error($curl));
            }
            return $response;
    }

     function HTML2OpenIDServer($content) {
        $get = array();

        // Get details of their OpenID server and (optional) delegate
        preg_match_all('/<link[^>]*rel=[\'"]openid.server[\'"][^>]*href=[\'"]([^\'"]+)[\'"][^>]*\/?>/i', $content, $matches1);
        preg_match_all('/<link[^>]*href=\'"([^\'"]+)[\'"][^>]*rel=[\'"]openid.server[\'"][^>]*\/?&开发者_StackOverflowgt;/i', $content, $matches2);
        $servers = array_merge($matches1[1], $matches2[1]);

        preg_match_all('/<link[^>]*rel=[\'"]openid.delegate[\'"][^>]*href=[\'"]([^\'"]+)[\'"][^>]*\/?>/i', $content, $matches1);

        preg_match_all('/<link[^>]*href=[\'"]([^\'"]+)[\'"][^>]*rel=[\'"]openid.delegate[\'"][^>]*\/?>/i', $content, $matches2);

        $delegates = array_merge($matches1[1], $matches2[1]);

        $ret = array($servers, $delegates);
        return $ret;
    }

    function GetOpenIDServer(){
        $response = $this->CURL_Request($this->openid_url_identity);
        list($servers, $delegates) = $this->HTML2OpenIDServer($response);
        if (count($servers) == 0){
            $this->ErrorStore('OPENID_NOSERVERSFOUND');
            return false;
        }
        if (isset($delegates[0])
          && ($delegates[0] != "")){
            $this->SetIdentity($delegates[0]);
        }
        $this->SetOpenIDServer($servers[0]);
        return $servers[0];
    }

    function GetRedirectURL(){
        $params = array();
        $params['openid.return_to'] = urlencode($this->URLs['approved']);
        $params['openid.mode'] = 'checkid_setup';
        $params['openid.identity'] = urlencode($this->openid_url_identity);
        $params['openid.trust_root'] = urlencode($this->URLs['trust_root']);

        if (isset($this->fields['required'])
          && (count($this->fields['required']) > 0)) {
            $params['openid.sreg.required'] = implode(',',$this->fields['required']);
        }
        if (isset($this->fields['optional'])
          && (count($this->fields['optional']) > 0)) {
            $params['openid.sreg.optional'] = implode(',',$this->fields['optional']);
        }
        return $this->URLs['openid_server'] . "?". $this->array2url($params);
    }

    function Redirect(){
        $redirect_to = $this->GetRedirectURL();
        if (headers_sent()){ // Use JavaScript to redirect if content has been previously sent (not recommended, but safe)
            echo '<script language="JavaScript" type="text/javascript">window.location=\'';
            echo $redirect_to;
            echo '\';</script>';
        }else{  // Default Header Redirect
            header('Location: ' . $redirect_to);
        }
    }

    function ValidateWithServer(){
        $params = array(
            'openid.assoc_handle' => urlencode($_GET['openid_assoc_handle']),
            'openid.signed' => urlencode($_GET['openid_signed']),
            'openid.sig' => urlencode($_GET['openid_sig'])
        );
        // Send only required parameters to confirm validity
        $arr_signed = explode(",",str_replace('sreg.','sreg_',$_GET['openid_signed']));
        for ($i=0; $i<count($arr_signed); $i++){
            $s = str_replace('sreg_','sreg.', $arr_signed[$i]);
            $c = $_GET['openid_' . $arr_signed[$i]];
            // if ($c != ""){
                $params['openid.' . $s] = urlencode($c);
            // }
        }
        $params['openid.mode'] = "check_authentication";

        $openid_server = $this->GetOpenIDServer();
        if ($openid_server == false){
            return false;
        }
        $response = $this->CURL_Request($openid_server,'POST',$params);
        $data = $this->splitResponse($response);

        if ($data['is_valid'] == "true") {
            return true;
        }else{
            return false;
        }
    }
}
?>


The problem is that Google doesn't just supply an OpenID endpoint.

OpenId endpoints include an identifier for the user.

What we are having here is called a Discovery Url.

This is a static url that you can direct any user to, and the service itself will recognise the user and return a per-user unique identifying url.

This however is NOT implemented correctly by most openid client libraries, including the majority linked on the official openid website.

Even the Zend Framework libraries are incapable of handling that.

However I found a class that I analysed from various perspectives and that I am very satisfied with. At the company I work at we already integrated it successfully in several production environments and have not experienced any problems.

You may also be interested in another post of mine dealing with the issue of making Facebook an openid Provider. The class I am using, that also supports Google, can also be found there:

Best way to implement Single-Sign-On with all major providers?


The class in your question does not support OpenID 2.0 at all. Therefore, it will not work with Google without adding a lot of code.


Are you searching something like : http://wiki.openid.net/w/page/12995176/Libraries ?

There is a PHP section in that.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜