自從學(xué)習(xí)微信開發(fā)就一直遇到大大小小的bug,每次的問題都是絞盡腦汁啊归苍。
最近測試剛完成的網(wǎng)頁授權(quán)獲取微信用戶信息功能突然出現(xiàn)了很多人都關(guān)注的錯誤挽拔,而且網(wǎng)上都沒有得到解決的錯誤?
現(xiàn)在終于得到完全解決话原,給走在路上或正在路上出現(xiàn)問題的伙伴一個走捷徑的方法。
問題描述:網(wǎng)頁授權(quán)獲取微信用戶信息 錯誤40029:不合法的oauth_code诲锹?
在第一步:用戶同意授權(quán)獲取code繁仁,通過code獲取access_token時,有時會出現(xiàn)40029錯誤归园。
經(jīng)過調(diào)試會發(fā)現(xiàn)問題出現(xiàn)在redirect_uri=REDIRECT_URI當(dāng)跳轉(zhuǎn)到授權(quán)鏈接后黄虱,微信會發(fā)出兩次轉(zhuǎn)向至redirect_uri的相同請求(兩次帶進(jìn)來的code是相同的)。
第一次的code后已經(jīng)成功換取得openid以及access_token庸诱;
第二次轉(zhuǎn)向到redirect_uri時捻浦,該code已經(jīng)失效(code只能使用一次),從而導(dǎo)致了40029:不合法的oauth_code的錯誤桥爽,不能再獲取到access_token朱灿。
可這種情況只是偶爾發(fā)生,過一會兒再進(jìn)入又正常了 钠四!
======================================================================
解決方案:
$code=$this->input->get("code");//獲取code
$dlzt=$this->input->cookie("dlzt"); //重點 ->此cookie用于記錄code是否重復(fù)提交
if (empty($code)) ? //不用說 通過empty函數(shù)判斷code是否設(shè)置值盗扒,沒有從小跳轉(zhuǎn)微信code獲取頁面或邏輯頁面
{
redirect("/wap/hy/index_hy"); ?//我這里跳轉(zhuǎn)的是邏輯頁面,視為code不存在視為不合法訪問缀去,因為正常訪問不會出現(xiàn)沒有code侣灶。
exit();
}
if(!empty($dlzt)) ? //上面說了 記錄code是否重復(fù)提交,此處就是判斷這個$dlzt存在了不執(zhí)行獲取用戶信息缕碎,因為用戶信息已經(jīng)獲取過了褥影。
{?
//重要說明:
這里放如果存在二次轉(zhuǎn)向到redirect_uri時,在這里進(jìn)行第二次跳轉(zhuǎn)的邏輯判斷咏雌,我此處是進(jìn)行登錄獲取用戶信息凡怎,因為第一次已經(jīng)登錄完成了校焦,登錄狀態(tài)和相關(guān)邏輯都已經(jīng)成功執(zhí)行一次,第二次我是直接跳入會員中心栅贴,就避免了第二次重復(fù)登錄出現(xiàn)code無限的錯誤了斟湃。
delete_cookie("dlzt");//刪除我們設(shè)置的$dlzt 這個cookie值,刪除好處是檐薯,用戶重新打開頁面或下次訪問頁面還是第一次訪問狀態(tài),不會出現(xiàn)因為有值而導(dǎo)致不執(zhí)行獲取微信用戶信息出錯注暗。
}else
{
//此處是完整的通過code來獲取accesstoken 及獲取用戶資料坛缕。
// 通過code 獲取 accessToken 和 openid
$res = $this->Weixin_model->getAccessToken($code);//這是我封裝的方法你們調(diào)用自己的方法。
if(!empty($res['errcode']))//判斷是否獲取到accesstoken ?防止偶爾的錯誤處理加個判斷有好處捆昏。
{
redirect('https://open.weixin.qq.com/connect/oauth2/authorize?appid=********&redirect_uri=http://www.baidu.com&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect');
exit();
}
$token=$res['access_token'];
$openid=$res['openid'];
//------ 檢測accesstoken是否有效
if (!$this->Weixin_model->checkAccessToken($token, $openid))
{
// (假設(shè)token過期需要從小獲取自己去判斷)
$restk = $this->Weixin_model->refreshToken($res['refresh_token']);
$token=$restk['access_token'];
}
//獲取用戶信息 ?(scope為 snsapi_userinfo)
$userInfo = $this->Weixin_model->getUserInfo($token, $openid);
$nickname=$userInfo['nickname'];//昵稱
$headimgurl=$userInfo['headimgurl'];//用戶頭像
$sex=$userInfo['sex'];//性別
$dlzt=$this->Login_model->Openid_login_hy($res['openid'],$nickname,$headimgurl,$sex);
$this->input->set_cookie("dlzt",$dlzt,120);
}