前言:
php实现qq快速登录,罗列了三种方法
方法一:面向过程,回调地址和首次触发登录写到了一个方法页面【因为有了if做判断】,
方法二,三:面向对象
1.先调用登录方法,向腾讯发送请求,
2.腾讯携带本网站唯一对应参数openid,accesstoken,返回到对应回调页面,
3.回调页面接受到腾讯的参数后,通过这个两个参数,再发出对应的请求,如查询用户的数据。
4.腾讯做出对应的操作,如返回这个用户的数据给你
即使你没看懂,也没关系,按照我下面的流程来,保证你可以实现。
前期准备:
使用人家腾讯的功能,总得和人家打招呼吧!
qq互联首页:http://connect.qq.com/
进入网址后,按如下操作来:
一.进入官网
二.申请创建【网站】应用
三.按要求填写资料
注意网站地址:填写你要设置快速登录的网址,eg:http://www.test.com;
回调地址:填写你发送qq快速登陆后,腾讯得给你信息,这个信息往此页面接受。eg:http://www.test.com/accept_info.php
【详细的申请填写,请见官方提示,这里不做赘述】
四.申请成功后,完善信息
最终要求,获得app_id ,app_key
五.代码部分:
在你对应的php文件内写入,如下
方法一,面向过程法
使用方法:配置$app_id,$app_secret,$my_url后,其他原封复制即可,$user_data为返回的登录信息
代码:
//应用的appid
$app_id = "你的appid";
//应用的appkey
$app_secret = "你的appkey";
//【成功授权】后的回调地址,即此地址在腾讯的信息中有储存
$my_url = "你的回调网址";
//step1:获取authorization code
session_start();
$code = $_request["code"];//存放authorization code
if(empty($code))
{
//state参数用于防止csrf攻击,成功授权后回调时会原样带回
$_session['state'] = md5(uniqid(rand(), true));
//拼接url
$dialog_url = "https://graph.qq.com/oauth2.0/authorize?response_type=code&client_id="
. $app_id . "&redirect_uri=" . urlencode($my_url) . "&state="
. $_session['state'];
echo("<script> top.location.href='" . $dialog_url . "'</script>");
}
//step2:通过authorization code获取access token
if($_request['state'] == $_session['state'] || 1)
{
//拼接url
$token_url = "https://graph.qq.com/oauth2.0/token?grant_type=authorization_code&"
. "client_id=" . $app_id . "&redirect_uri=" . urlencode($my_url)
. "&client_secret=" . $app_secret . "&code=" . $code;
$response = file_get_contents($token_url);
if (strpos($response, "callback") !== false)//如果登录用户临时改变主意取消了,返回true!==false,否则执行step3
{
$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;
}
}
//step3:使用access token来获取用户的openid
$params = array();
parse_str($response, $params);//把传回来的数据参数变量化
$graph_url = "https://graph.qq.com/oauth2.0/me?access_token=".$params['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);//存放返回的数据 client_id ,openid
if (isset($user->error))
{
echo "<h3>error:</h3>" . $user->error;
echo "<h3>msg :</h3>" . $user->error_description;
exit;
}
//echo("hello " . $user->openid);
//echo("hello " . $params['access_token']);
//step4:使用<span style="font-family: arial, helvetica, sans-serif;">openid,</span><span style="font-family: arial, helvetica, sans-serif;">access_token来获取所接受的用户信息。</span>
$user_data_url = "https://graph.qq.com/user/get_user_info?access_token={$params['access_token']}&oauth_consumer_key={$app_id}&openid={$user->openid}&format=json";
$user_data = file_get_contents($user_data_url);//此为获取到的user信息
}
else
{
echo("the state does not match. you may be a victim of csrf.");
}
方法二,面向对象 使用类qq_loginaction.class
使用方法:
1.在qq_loginaction.class中正确配置 appid,appkey callback(回调网址)
2.在调用方法中,代码:
$qq_login = new componentqq_loginaction(); //引入此类文件即可
$qq_login->qq_login(); //调用登录方法,向腾讯发出快速登录请求
3.在回调页面中,代码:
$qc = new componentqq_loginaction();
$acs = $qc->qq_callback();<span style="white-space:pre"> //access_token
$oid=$qc->get_openid();<span style="white-space:pre"> //openid
$user_data = $qc->get_user_info();<span style="white-space:pre"> //get_user_info()为获得该用户的信息,其他操作方法见api文档
4.$user_data即为返回的用户数据。
5.qq_loginaction.class.php 文件代码:【用的thinkphp3.2】
<?php
namespace component;
session_start();
define('appid','xxxx'); //appid
define('appkey','xxxx'); //appkey
define('callback','xxxx'); //回调地址
define('scope','get_user_info,list_album,add_album,upload_pic,add_topic,add_weibo'); //授权接口列表
class qq_loginaction {
const get_auth_code_url = "https://graph.qq.com/oauth2.0/authorize";
const get_access_token_url = "https://graph.qq.com/oauth2.0/token";
const get_openid_url = "https://graph.qq.com/oauth2.0/me";
private $apimap = array(
"get_user_info" => array( //获取用户资料
"https://graph.qq.com/user/get_user_info",
array("format" => "json"),
),
"add_t" => array( //发布一条普通微博
"https://graph.qq.com/t/add_t",
array("format" => "json", "content","#clientip","#longitude","#latitude","#compatibleflag"),
"post"
),
"add_pic_t" => array( //发布一条图片微博
"https://graph.qq.com/t/add_pic_t",
array("content", "pic", "format" => "json", "#clientip", "#longitude", "#latitude", "#syncflag", "#compatiblefalg"),
"post"
),
"del_t" => array( //删除一条微博
"https://graph.qq.com/t/del_t",
array("id", "format" => "json"),
"post"
),
"get_repost_list" => array( //获取单条微博的转发或点评列表
"https://graph.qq.com/t/get_repost_list",
array("flag", "rootid", "pageflag", "pagetime", "reqnum", "twitterid", "format" => "json")
),
"get_info" => array( //获取当前用户资料
"https://graph.qq.com/user/get_info",
array("format" => "json")
),
"get_other_info" => array( //获取其他用户资料
"https://graph.qq.com/user/get_other_info",
array("format" => "json", "#name-1", "#fopenid-1")
),
"get_fanslist" => array(
"https://graph.qq.com/relation/get_fanslist", //我的微博粉丝列表
array("format" => "json", "reqnum", "startindex", "#mode", "#install", "#sex")
),
"get_idollist" => array(
"https://graph.qq.com/relation/get_idollist", //我的微博收听列表
array("format" => "json", "reqnum", "startindex", "#mode", "#install")
),
"add_idol" => array(
"https://graph.qq.com/relation/add_idol", //微博收听某用户
array("format" => "json", "#name-1", "#fopenids-1"),
"post"
),
"del_idol" => array( //微博取消收听某用户
"https://graph.qq.com/relation/del_idol",
array("format" => "json", "#name-1", "#fopenid-1"),
"post"
)
);
private $keysarr;
function __construct(){
if($_session["openid"]){
$this->keysarr = array(
"oauth_consumer_key" => appid,
"access_token" => $_session['access_token'],
"openid" => $_session["openid"]
);
}else{
$this->keysarr = array(
"oauth_consumer_key" => appid
);
}
}
public function qq_login(){
//-------生成唯一随机串防csrf攻击
$_session['state'] = md5(uniqid(rand(), true));
$keysarr = array(
"response_type" => "code",
"client_id" => appid,
"redirect_uri" => callback,
"state" => $_session['state'],
"scope" => scope
);
$login_url = self::get_auth_code_url.'?'.http_build_query($keysarr);
header("location:$login_url");
}
public function qq_callback(){
//--------验证state防止csrf攻击
if($_get['state'] != $_session['state']){
return false;
}
//-------请求参数列表
$keysarr = array(
"grant_type" => "authorization_code",
"client_id" => appid,
"redirect_uri" => callback,
"client_secret" => appkey,
"code" => $_get['code']
);
//------构造请求access_token的url
$token_url = self::get_access_token_url.'?'.http_build_query($keysarr);
$response = $this->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)){
$this->showerror($msg->error, $msg->error_description);
}
}
$params = array();
parse_str($response, $params);
$_session["access_token"]=$params["access_token"];
$this->keysarr['access_token']=$params['access_token'];
return $params["access_token"];
}
public function get_contents($url){
if (ini_get("allow_url_fopen") == "1") {
$response = file_get_contents($url);
}else{
$ch = curl_init();
curl_setopt($ch, curlopt_ssl_verifypeer, false);
curl_setopt($ch, curlopt_returntransfer, true);
curl_setopt($ch, curlopt_url, $url);
$response = curl_exec($ch);
curl_close($ch);
}
if(empty($response)){
return false;
}
return $response;
}
public function get_openid(){
//-------请求参数列表
$keysarr = array(
"access_token" => $_session["access_token"]
);
$graph_url = self::get_openid_url.'?'.http_build_query($keysarr);
$response = $this->get_contents($graph_url);
//--------检测错误是否发生
if(strpos($response, "callback") !== false){
$lpos = strpos($response, "(");
$rpos = strrpos($response, ")");
$response = substr($response, $lpos + 1, $rpos - $lpos -1);
}
$user = json_decode($response);
if(isset($user->error)){
$this->showerror($user->error, $user->error_description);
}
//------记录openid
$_session['openid']=$user->openid;
$this->keysarr['openid']=$user->openid;
return $user->openid;
}
/**
* showerror
* 显示错误信息
* @param int $code 错误代码
* @param string $description 描述信息(可选)
*/
public function showerror($code, $description = '$'){
echo "<meta charset="utf-8">";
echo "<h3>error:</h3>$code";
echo "<h3>msg :</h3>$description";
exit();
}
/**
* _call
* 魔术方法,做api调用转发
* @param string $name 调用的方法名称
* @param array $arg 参数列表数组
* @since 5.0
* @return array 返加调用结果数组
*/
public function __call($name,$arg){
//如果apimap不存在相应的api
if(empty($this->apimap[$name])){
$this->showerror("api调用名称错误","不存在的api: <span style='color:red;'>$name</span>");
}
//从apimap获取api相应参数
$baseurl = $this->apimap[$name][0];
$argslist = $this->apimap[$name][1];
$method = isset($this->apimap[$name][2]) ? $this->apimap[$name][2] : "get";
if(empty($arg)){
$arg[0] = null;
}
$responsearr = json_decode($this->_applyapi($arg[0], $argslist, $baseurl, $method),true);
//检查返回ret判断api是否成功调用
if($responsearr['ret'] == 0){
return $responsearr;
}else{
$this->showerror($responsearr['ret'], $responsearr['msg']);
}
}
//调用相应api
private function _applyapi($arr, $argslist, $baseurl, $method){
$pre = "#";
$keysarr = $this->keysarr;
$optionarglist = array();//一些多项选填参数必选一的情形
foreach($argslist as $key => $val){
$tmpkey = $key;
$tmpval = $val;
if(!is_string($key)){
$tmpkey = $val;
if(strpos($val,$pre) === 0){
$tmpval = $pre;
$tmpkey = substr($tmpkey,1);
if(preg_match("/-(d$)/", $tmpkey, $res)){
$tmpkey = str_replace($res[0], "", $tmpkey);
$optionarglist[]= $tmpkey;
}
}else{
$tmpval = null;
}
}
//-----如果没有设置相应的参数
if(!isset($arr[$tmpkey]) || $arr[$tmpkey] === ""){
if($tmpval == $pre){
continue;
}else if($tmpval){//则使用默认的值
$arr[$tmpkey] = $tmpval;
}else{
$this->showerror("api调用参数错误","未传入参数$tmpkey");
}
}
$keysarr[$tmpkey] = $arr[$tmpkey];
}
//检查选填参数必填一的情形
if(count($optionarglist)!=0){
$n = 0;
foreach($optionarglist as $val){
if(in_array($val, array_keys($keysarr))){
$n++;
}
}
if(!$n){
$str = implode(",",$optionarglist);
$this->showerror("api调用参数错误",$str."必填一个");
}
}
if($method == "post"){
$response = $this->post($baseurl, $keysarr, 0);
}else if($method == "get"){
$baseurl=$baseurl.'?'.http_build_query($keysarr);
$response = $this->get_contents($baseurl);
}
return $response;
}
public function post($url, $keysarr, $flag = 0){
$ch = curl_init();
if(! $flag) curl_setopt($ch, curlopt_ssl_verifypeer, false);
curl_setopt($ch, curlopt_returntransfer, true);
curl_setopt($ch, curlopt_post, true);
curl_setopt($ch, curlopt_postfields, $keysarr);
curl_setopt($ch, curlopt_url, $url);
$ret = curl_exec($ch);
curl_close($ch);
return $ret;
}
}
方法三,面向对象 使用腾讯给的sdk
使用方法:腾讯sdk,api写的很详细,不做赘述
地址:http://wiki.connect.qq.com/%e7%bd%91%e7%ab%99%e6%8e%a5%e5%85%a5%e6%a6%82%e8%bf%b0
这样就实现了qq快捷登录,其实很简单的,大家可以试一试。
还有什么不清楚的,可以看看官方介绍,更详细,
tips:如何在本地测试qq快速登录
方法:修改host配置文件
1. 打开c:windowssystem32driversetchost
2. 添加127.0.0.1 www.test.com
然后操作就可以了。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持硕编程。
【说明】:
本文章由站长整理发布,文章内容不代表本站观点,如文中有侵权行为,请与本站客服联系(QQ:254677821)!