微信第三方登陆受权后,能获取到code码,可是获取gat_token()信息就会返回这样的错误信息:php
Array ( [errcode] => 40029 [errmsg] => invalid code, hints: [ req_id: jGkksa0933ssz5 ] )
有问题,先查下官方的文档,熟悉下受权流程:html
微信第三方受权登陆文档:http://blog.csdn.net/iamduoluo/article/details/40384419前端
官方文档:json
http://mp.weixin.qq.com/wiki/17/c0f37d5704f0b64713d5d2c37b468d75.htmlapi
网页受权流程分为四步:数组
一、引导用户进入受权页面赞成受权,获取code 二、经过code换取网页受权access_token(与基础支持中的access_token不一样) 三、若是须要,开发者能够刷新网页受权access_token,避免过时 四、经过网页受权access_token和openid获取用户基本信息(支持UnionID机制)
知乎上边的答案:缓存
微信公众号错误提示:{"errcode":40029,"errmsg":"invalid code"} code失效求解决方案(code只能被使用一次)微信
code失效,是由于你重复请求了,请求两次致使code失效(code只能使用一次)app
http://www.zhihu.com/question/33594002curl
小结:
通过翻官方文档,网上查解决的方法,终于解决了这个问题 ^_^
有两个问题须要注意:
第一,code不能重复请求,这个能够经过在微信请求的登陆页面header("Location: ".$url);以前加个log记录或记录到缓存数组中,看一共请求了几回。
第二,在用curl获取Token信息时,会由于 api.weixin.qq.com域名解析慢的问题,出现超时,致使不能根据code码获取到token,解决方法能够看个人另外一篇博客http://my.oschina.net/corwien/blog/674496。
还要注意一点,为避免问题一的出现,咱们应该将微信请求的登陆页面(获取受权后返回code码)和回调页面(根据code码获取token信息,而后处理本身的业务逻辑)分开写,以前是因为偷懒,全都写在一块了。
微信请求登陆页面 index.php:
<?php /** * ---------------------------------------------------------------- * 微信登陆-请求页面 * ---------------------------------------------------------------- * [访问URL] * http://mysite.com/partner_login/index.php * ---------------------------------------------------------------- * [功能描述] * 用于前端页面请求调用微信登陆界面的入口 * ---------------------------------------------------------------- * [参数说明] * redirect_url string 跳转回网站的地址,默认:'http://m.baidu.com/' * ---------------------------------------------------------------- * @author Corwien * @version 2016-05 * ---------------------------------------------------------------- */ // 微信服务号 $appid = 'wxwxxxxxxxxxxxxxx'; // 获取参数,前端传过来须要跳转回的连接 $return_url = $_GET['return_url']; $return_url = !empty($return_url) ? $return_url : 'http://m.baidu.com/'; // 添加随机值 $rand_num = rand(1,10000); // 回调页面 $call_url = 'http://mysite.com/partner_login/callback.php'; // 连接 $redirect_uri = urlencode($call_url.'?goback_url='.$return_url); $url = 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.$redirect_uri.'&response_type=code&no='.$rand_num.'&scope=snsapi_userinfo&state=STATE&connect_redirect=1#wechat_redirect'; // 能够在此添加日志或缓存记录,查看这个页面是否请求了两次 // 请求微信 header("Location: ".$url); ?>
回调页面callback.php:
<?php /** * ---------------------------------------------------------------- * 微信登陆-回调页面 * ---------------------------------------------------------------- * [访问URL] * http://mysite.com/partner_login/callback.php * ---------------------------------------------------------------- * [功能描述] * 用于获取第三方用户信息 * ---------------------------------------------------------------- * [参数说明] * goback_url string 跳转回网站的地址 * code string 受权后的Code码 * ---------------------------------------------------------------- * @author Corwien * @version 2016-05 * ---------------------------------------------------------------- */ // 微信服务号 $appid = 'WXXXXXXXXXXXXXXXXXXXX'; $secret = 'OOOOOOOOOOXXXXXXXXXXXXXX'; // 获取code码 $code = isset($_GET['code']) ? $_GET['code'] : false; $goback_url = isset($_GET['goback_url']) ? $_GET['goback_url'] : null; // 校验code码 if(empty($code)) { die('Not allow!'); } if($code && $goback_url) { // 获取Token信息 $token_info = get_token(array('appid'=>$appid, 'secret'=>$secret, 'code'=>$code)); // 判断受权是否成功 if(empty($token_info['access_token']) || empty($token_info['openid']) || empty($token_info['unionid'])) { die('受权Token失败!'); } // 获取用户信息 $user = get_user($token_info); $user = eval('return ' . mb_convert_encoding(var_export($user,true), 'GBK', 'UTF-8') . ';'); // 微信的用户信息获取到手了,而后接下来处理本身的业务逻辑,保存相关的信息,而后登录本身的网站 // ... // ... // ... } else { die('404'); } function get_token($options) { $appid = $options['appid']; $secret = $options['secret']; $code = $options['code']; $url = 'https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$appid.'&secret='.$secret.'&code='.$code.'&grant_type=authorization_code'; $curl = curl_init (); curl_setopt ( $curl, CURLOPT_URL, $url ); curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, FALSE ); curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, FALSE ); curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 ); $output = curl_exec ( $curl ); curl_close ( $curl ); return json_decode($output, true); } function get_user($options) { $access_token = $options['access_token']; $openid = $options['openid']; $url = 'https://api.weixin.qq.com/sns/userinfo?access_token='.$access_token.'&openid='.$openid.'&lang=zh_CN'; $curl = curl_init (); curl_setopt ( $curl, CURLOPT_URL, $url ); curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, FALSE ); curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, FALSE ); curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 ); $output = curl_exec ( $curl ); curl_close ( $curl ); return json_decode($output, true); } ?>
###封装的Qzone第三方curl获取TOken和用户信息的方法
```
// curl 请求获取远程数据,file_get_contents获取数据太慢了【2016-05-19】
function do_http($url)
{
// 域名解析太慢,将域名替换为IP openapi.qzone.qq.com =》 183.60.15.158
$url = str_replace('openapi.qzone.qq.com', '183.60.15.158', $url);
$curl = curl_init ();
curl_setopt ( $curl, CURLOPT_URL, $url );
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Host:openapi.qzone.qq.com'));
curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, FALSE );
curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );
$output = curl_exec ( $curl );
curl_close ( $curl );
// return json_decode($output, true);
return $output;
}
```