很多网站都有第三方登录,比如QQ登陆。
这里我说下关于我们网站上嵌入第三方QQ登陆的过程。
第一:首先,http://connect.qq.com/manage/index进入该网站,当然了,首先要有QQ账号登陆,填写完成开发者账号信息,都要是真实的。
第二:在管理中心创建应用。选择是什么类型的应用(手机应用或网站),然后根据提示进行填写内容。
第三:创建应用填写的内容必须真实有效,最主要的是网站地址以及回调地址的填写,网站地址输入之后,会有验证,然后需要根据你的QQ开发者账号生成的代码放置到网站的第一个页面的head标签中<meta property="qc:admins" content="244576065114774636" />,这样才能验证通过。回调地址填写的是在QQ登陆后返回到咱们网站的哪个页面(这个也可以直接写网站地址,回调地址可以在代码中进行控制)
第四:填写完成之后,点击创建应用,然后需要等待QQ那边的应用审核,应用必须审核通过才可以正常上线使用。
第五:要想审核通过:
1、用到QQ登陆的网页必须要QQ登陆按钮,而且该按钮布局必须规范,否则审核是不会通过的。
2、引入QQ登陆的API,里面有个config.php文件,需要对这些内容进行更改
//申请到的appid
$_SESSION["appid"] = 100575787;
//申请到的appkey
$_SESSION["appkey"] = "b235e4af033f8c776813566342c58fc2";
//QQ登录成功后跳转的地址,请确保地址真实可用,否则会导致登录失败。
$_SESSION["callback"] = "http://meditool.cn/Login/qqcallback";
//QQ授权api接口.按需调用
$_SESSION["scope"] = "get_user_info,add_share,add_topic,add_weibo";
?>
3、在登陆页面的QQ登陆按钮的onclick触发事件为下面代码的一个方法。这里我是让它跳转的另一个页面。
function toQzoneLogin()
{
var A=window.open("/index/qqlogin","TencentLogin","width=450,height=320,menubar=0,scrollbars=1, resizable=1,status=1,titlebar=0,toolbar=0,location=1");
}
4、qqlogin.phtml文件内容是这样的
<?php
if(!isset($_SESSION))
{
session_start();
}
require_once APPLICATION_PATH.\'/views/scripts/index/comm/config.php\';
function qq_login($appid, $scope, $callback)
{
$_SESSION[\'state\'] = md5(uniqid(rand(), TRUE)); //CSRF protection
. $appid . "&redirect_uri=" . urlencode($callback)
. "&state=" . $_SESSION[\'state\']
. "&scope=".$scope;
header("Location:$login_url");
}
//用户点击qq登录按钮调用此函数
qq_login($_SESSION["appid"], $_SESSION["scope"], $_SESSION["callback"]);
?>
5、这样做完之后,前期作业就完成了,但是这以上步骤只是可以有QQ登陆的第三方的页面,但是后期如何操作,主要还在第6步。
6、我们在配置文件中设置了我们QQ登陆后的回调地址,http://meditool.cn/Login/qqcallback,然后我们现在看下在LoginController文件中的qqcallback的Action中的执行代码:
if(!isset($_SESSION))
{
session_start();
}
if($_REQUEST[\'state\'] == $_SESSION[\'state\']) //csrf这个是QQ为了确保安全性,在QQ登陆的时候生成这么一个随机字符串,然后在回调过来的时候验证是否相等。
{
//这一步主要是为了获得授权令牌Access Token并保存到session中
. "client_id=" . $_SESSION["appid"]. "&redirect_uri=" . urlencode($_SESSION["callback"])
. "&client_secret=" . $_SESSION["appkey"]. "&code=" . $_REQUEST["code"];
$response = file_get_contents($token_url);
if (strpos($response, "callback") !== false)
{
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos -1);
$msg = json_decode($response);
if (isset($msg->error))
{
echo "<h3>error:</h3>" . $msg->error;
echo "<h3>msg :</h3>" . $msg->error_description;
exit;
}
}
$params = array();
parse_str($response, $params);
//debug
//print_r($params);
//set access token to session
$_SESSION["access_token"] = $params["access_token"];
//因为上面一步获得的授权有效期默认是三个月,所以这里我们将权限自动续期
. "client_id=" . $_SESSION["appid"]
. "&client_secret=" . $_SESSION["appkey"]. "&refresh_token=" . $params["refresh_token"];
$response = file_get_contents($token_url);
if (strpos($response, "callback") !== false)
{
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos -1);
$msg = json_decode($response);
if (isset($msg->error))
{
echo "<h3>error:</h3>" . $msg->error;
echo "<h3>msg :</h3>" . $msg->error_description;
exit;
}
}
$params = array();
parse_str($response, $params);
//debug
//print_r($params);
//set access token to session
$_SESSION["access_token"] = $params["access_token"];
}
else
{
echo("The state does not match. You may be a victim of CSRF.");
}
//根据前面几步得到的授权令牌进一步得到openid(这个就类似于用户QQ账号,但是QQ必须保证用户的信息安全性,所以是不可能获得用户的账号密码等信息的,这个openid就是QQ账号的替代品也是一个QQ账号一个openid)
$graph_url = "https://graph.qq.com/oauth2.0/me?access_token="
. $_SESSION[\'access_token\'];
$str = file_get_contents($graph_url);
if (strpos($str, "callback") !== false)
{
$lpos = strpos($str, "(");
$rpos = strrpos($str, ")");
$str = substr($str, $lpos + 1, $rpos - $lpos -1);
}
$user = json_decode($str);
if (isset($user->error))
{
echo "<h3>error:</h3>" . $user->error;
echo "<h3>msg :</h3>" . $user->error_description;
exit;
}
//debug
//echo("Hello " . $user->openid);
//set openid to session
$_SESSION["openid"] = $user->openid;
//我们现在就可以根据openid得到用户信息(只能得到用户的昵称,性别,控件头像,QQ头像,详细API参考QQ的API列表http://wiki.connect.qq.com/api%e5%88%97%e8%a1%a8)
$get_user_info = "https://graph.qq.com/user/get_user_info?"
. "access_token=" . $_SESSION[\'access_token\']
. "&oauth_consumer_key=" . $_SESSION["appid"]
. "&openid=" . $_SESSION["openid"]
. "&format=json";
$info = file_get_contents($get_user_info);
$arr = json_decode($info, true);
//下面就是将用户信息保存到咱们的数据库中,查询是否有该qq用户(这里我们就是根据前面得到的唯一值的openid来判断)然后就可以登陆咱们的网站了
$userModel=new Users();
$where="IDCard=\'".$_SESSION["openid"]."\'";
$loginuser=$userModel->fetchAll($where)->toArray();
if(count($loginuser)>0)//说明有 就直接登陆
{
//取出保存到session中
if(!isset($_SESSION))
{
session_start();
}
if($loginuser[0][\'UserName\']!=$arr[\'nickname\'])//昵称更换,同时更新数据库用户名
{
$data=array(
\'UserName\'=>$arr[\'nickname\'],
\'FullName\'=>$arr[\'nickname\']
);
$where="IDCard=\'".$_SESSION["openid"]."\'";
$userModel->update($data,$where);
}
$_SESSION[\'loginuser\']=$loginuser[0];
$_SESSION[\'loginuser\'][\'UserName\']=$arr[\'nickname\']; //session中的用户名更新
$_SESSION[\'loginuser\'][\'FullName\']=$arr[\'nickname\']; //session中的用户名更新
$this->forward(\'godefault\',\'My\');
}
else //说明没有;插入数据库,然后存入session
{
//数据信息存入数据库中
$userModel=new Users();
$db=$userModel->getAdapter();
$now=date("Y-m-d H:i:s");
$data=array(
\'UserName\'=>$arr[\'nickname\'],
\'FullName\'=>$arr[\'nickname\'],
\'UserPsw\'=>sha1(0),
\'RegTime\'=>$now,
\'LastTime\'=>$now,
\'PartmentName\'=>"",
\'Interesting\'=>"",
\'WebInviter\'=>"",
\'LinkMail\'=>"",
\'RegLevel\'=>0,
\'IsFrob\'=>\'0\',
\'UserImage\'=>$arr[\'figureurl_qq_1\'],
\'UserType\'=>0,
\'IDCard\'=>$_SESSION["openid"]
);
$loginuser=$userModel->insert($data);
//查询注册用户信息
$userModel=new Users();
$where="UserID=$loginuser";
$loginuser=$userModel->fetchAll($where)->toArray();
//取出保存到session中
//session_start();
if(!isset($_SESSION))
{
session_start();
}
$_SESSION[\'loginuser\']=$loginuser[0];
$this->forward(\'godefault\',\'My\');
}
}
六、经过第五步中的几个步骤操作无误完成之后,提交审核,一般情况一天到三天之内就可以通过审核。