上次写了Windows Live ID当作OpenID使用的方法,这次写Google的OpenID的实现方法。


if(empty($_REQUEST['openid_mode'])){
$openid_server = getXrdsUri('https://www.google.com/accounts/o8/id');
$data['openid.ns'] = 'http://specs.openid.net/auth/2.0';
$data['openid.mode'] = 'associate';
$data['openid.assoc_type'] = 'HMAC-SHA1';
$data['openid.session_type'] = 'no-encryption';
$AssocHandle = getAssociationHandle($openid_server.'?'.http_build_query($data));
setcookie('cookieAssocHandle', $AssocHandle);
unset($data);

$data['openid.ns'] = 'http://specs.openid.net/auth/2.0';
$data['openid.claimed_id'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$data['openid.identity'] = 'http://specs.openid.net/auth/2.0/identifier_select';
$data['openid.return_to'] = $AuthUrl;
$data['openid.realm'] = $RealmUrl;
$data['openid.assoc_handle'] = $AssocHandle;
$data['openid.mode'] = 'checkid_setup';
$data['openid.ns.ext1'] = 'http://openid.net/srv/ax/1.0';
$data['openid.ext1.mode'] = 'fetch_request';
$data['openid.ext1.type.email'] = 'http://axschema.org/contact/email';
$data['openid.ext1.required'] = 'email';

$LocationUrl = $openid_server.'?'.http_build_query($data);
}else{
if('id_res' == $_REQUEST['openid_mode']
&& $AssocHandle == $_REQUEST['openid_assoc_handle']){
$openid = !empty($_REQUEST['openid_ext1_value_email']) ? $_REQUEST['openid_ext1_value_email'] : formUrl($_REQUEST['openid_claimed_id']);
$email = $_REQUEST['openid_ext1_value_email'];
}
echo('<pre>');
echo("<a href=$LoginUrl>BACK</a>\n\n");
print_r($_REQUEST);
echo('</pre>');
}

function getAssociationHandle($url){
$c = curl_init($url);

curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);

$contents = curl_exec($c);
//print_r($contents);
//exit;

curl_close($c);

$assoc_handle = time();

$lines = explode("\n", $contents);

foreach($lines as $line){
if(substr($line, 0, 13) == "assoc_handle:"){
$assoc_handle = substr($line, 13);
break;
}
}

return $assoc_handle;
}

function getXrdsUri($url){
$c = curl_init($url);

curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_HEADER, false);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);

$request_contents = curl_exec($c);

curl_close($c);

$domdoc = new DOMDocument();
$domdoc->loadXML($request_contents);

$uri = $domdoc->getElementsByTagName("URI");
$uri = $uri->item(0)->nodeValue;

return $uri;
}

if(empty($openid))
LocationHtml($LocationUrl);

LocationHtml函数见Windows Live ID当作OpenID使用的方法

注意:Google的OpenID的openid.claimed_id(即OpenID)的值,随不同网站变化,网站不同值也不同,所以不是真正的OpenID,Google真正的OpenID是他的Email。但是Email也不是每次都可以取得到的,如果你在Google的授权页面上点选了”允许 XXX 记住我”,再次登录时将略过授权页面,同时也将得不到Email的值。只有Google帐号的所有者在个人设置里更改获授权网站,将你的网站撤销访问权,才能再次得到Email的值。

Google的OpenID是个被阉割的OpenID,除了提供Email的值之外,其他一概不提供!

参考:http://code.google.com/intl/zh-CN/apis/accounts/docs/OpenID.html

24 Comments

  • lo

    getXrdsUri 是什麼 ???

  • lo

    阿 , 看到了 , 只掛住看 LocationHtml 部份

  • 王炜

    解决问题了吗?不知对你是否有帮助!

  • lo

    http://58.64.129.11/sample/

    不能

    Fatal error: Cannot redeclare getxrdsuri()

  • 王炜

    getXrdsUri注意大小写
    PHP是否开通CURL

  • lo

    已開通

    curl
    cURL support enabled
    cURL Information libcurl/7.19.4 OpenSSL/0.9.8k zlib/1.2.3

    還是不行

  • 王炜

    参考: http://wangblog.org/2009/05/openid-google-yahoo-windows-live-id.html

    是完整的代码,你复制运行下,看看有问题吗!

  • lo

    在Apache的httpd.conf的文件中配置一下:
    LoadFile “D:/webserver/php/ssleay32.dll”
    LoadFile “D:/webserver/php/libeay32.dll”

    還是

    libeay32.dll, ssleay32.dll, php5ts.dll, php_curl.dll
    feedom.net

    都拷贝到system32目录下 ???

  • 王炜

    PHP在WIN下我忘了怎么配置了,现在都是用FreeBSD的系统!

    Google下教程吧!

  • lo

    http://wangblog.org/2009/05/openid-google-yahoo-windows-live-id.html
    全部跟你的話

    Notice: Undefined variable: fullname in /usr/local/www/apache22/data/freebapp.org/tools/openid/auth.php on line 246

    fullname:

    Notice: Undefined variable: nickname in /usr/local/www/apache22/data/freebapp.org/tools/openid/auth.php on line 247

    nickname:

    Notice: Undefined variable: timezone in /usr/local/www/apache22/data/freebapp.org/tools/openid/auth.php on line 248

    timezone:

  • 王炜

    error_reporting(0);
    //ini_set(‘error_reporting’, E_ALL);
    //ini_set(“display_errors”, 1);

    可以屏蔽的警告,不要紧的!

  • lo

    還未訓 =3=

    即是只能得到 google 上用戶的 email ???

  • lo

    [如果你在Google的授权页面上点选了”允许 XXX 记住我”,再次登录时将略过授权页面,同时也将得不到Email的值。只有Google帐号的所有者在个人设置里更改获授权网站,将你的网站撤销访问权,才能再次得到Email的值。]

    即是 $openid 唔會變 ??? $email 會變 ???

    然後用 $openid 當作用戶的 name 和 ID 啦 @_@

  • lo

    還有如何登出 , post 埋出來 la , THX 大大 >3<

  • 王炜

    Google不遵守标准的OpenID标准,$_REQUEST[‘openid_claimed_id’]的值会随openid.realm的变化而不同,也就是说不同的网站得到的$_REQUEST[‘openid_claimed_id’]是不同的!

  • lo

    咁我用那個依歸好呢 ???? -0-

  • lo

    Google不遵守标准的OpenID标准,$_REQUEST[‘openid_claimed_id’]的值会随openid.realm的变化而不同,也就是说不同的网站得到的$_REQUEST[‘openid_claimed_id’]是不同的!

    如果搬站那何大件事 = =

  • 王炜

    用$_REQUEST[‘openid_claimed_id’]吧

  • lo

    休息去 , 明天再傾 la ^_^
    你也早點休息吧 ~”~

  • lo

    昨日說到 登入後 如何登出 ????

  • lo

    https://www.google.com/accounts/Logout

    原來 logout 只要 link to logout page 咋 ,
    這樣簡單 = =

  • luoyf

    formUrl的声明没见,请问:我在哪里能找到formUrl的声明。谢谢!

Leave a Reply to lo Cancel reply