轉自:微信授權錯誤:"errcode":40163,"errmsg":"codebeenused 微信網頁授權獲取code值回調兩次的問題 1.說是功能變數名稱原因,目前未測試,沒有正確的功能變數名稱 問題描述:在調用微信網頁授權獲取openid值時,先獲取的code值,但是code值的介面 會走兩次回調。而cod ...
轉自:微信授權錯誤:"errcode":40163,"errmsg":"codebeenused
微信網頁授權獲取code值回調兩次的問題
1.說是功能變數名稱原因,目前未測試,沒有正確的功能變數名稱
- 問題描述:在調用微信網頁授權獲取openid值時,先獲取的code值,但是code值的介面 會走兩次回調。而code在6分鐘內只能用一次,所以處出現code失效的問題,問題顯示錯誤碼:{‘errcode’:40029,’errmsg’:’invalid code, hints: [ req_id: 0407ns44 ]’}
- 解決辦法: 出現這個問題是因為功能變數名稱的問題,本人先使用的花生殼的內網穿透,但是花生殼的免費功能變數名稱應用的是第三方代理功能變數名稱,所以在向微信伺服器發送請求的時候,微信回調時,會認為你的功能變數名稱請求不一致,會回調兩次,重定向你的伺服器兩次,只需更改正式功能變數名稱即可。就會回調一次。(網上說的返回值結束二次回調,和301重定向 都是坑人的,折騰一天還是功能變數名稱問題
2.說需要一個參數 &connect_redirect=1,這個是解決40029的錯誤
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
//實際使用生成url的代碼 <br>string UrlUserInfo = OAuthApi.GetAuthorizeUrl(AppId,
"http://2a20h48668.imwork.net/weixin/UserInfoCallback?returnUrl=" + returnUrl.UrlEncode(),
state, OAuthScope.snsapi_userinfo);
// 摘要:
// 獲取驗證地址的API,以及參數說明
//
// 參數:
// appId:
// 公眾號的唯一標識
//
// redirectUrl:
// 授權後重定向的回調鏈接地址,請使用urlencode對鏈接進行處理
//
// state:
// 重定向後會帶上state參數,開發者可以填寫a-zA-Z0-9的參數值,最多128位元組
//
// scope:
// 應用授權作用域,snsapi_base (不彈出授權頁面,直接跳轉,只能獲取用戶openid),snsapi_userinfo (彈出授權頁面,可通過openid拿到昵稱、性別、所在地。並且,即使在未關註的情況下,只要用戶授權,也能獲取其信息)
//
// responseType:
// 返回類型,請填寫code(或保留預設)
//
// addConnectRedirect:
// 加上後可以解決40029-invalid code的問題(測試中)
public static string GetAuthorizeUrl( string appId, string redirectUrl, string state, OAuthScope scope, string responseType = "code" , bool addConnectRedirect = true );
|
最終網址結果
https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxd84d9cb4875236c9&redirect_uri=http%3A%2F%2F2a20h48668.imwork.net%2Fweixin%2FUserInfoCallback%3FreturnUrl%3D%252FWeixinJSSDK%252Findex&response_type=code&scope=snsapi_userinfo&state=JeffreySu-954&connect_redirect=1#wechat_redirect
3.訪問的地址是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
/// <summary>
/// OAuthScope.snsapi_userinfo方式回調
/// </summary>
/// <param name="code"></param>
/// <param name="state"></param>
/// <param name="returnUrl">用戶最初嘗試進入的頁面</param>
/// <returns></returns>
public ActionResult UserInfoCallback( string code, string state, string returnUrl)
{
if ( string .IsNullOrEmpty(code))
{
return Content( "您拒絕了授權!" );
}
var orginState = data.getState();
if (state != orginState)
{
//這裡的state其實是會暴露給客戶端的,驗證能力很弱,這裡只是演示一下,
//建議用完之後就清空,將其一次性使用
//實際上可以存任何想傳遞的數據,比如用戶ID,並且需要結合例如下麵的Session["OAuthAccessToken"]進行驗證
return Content( "驗證失敗!請從正規途徑進入!" );
}
OAuthAccessTokenResult result = null ;
//通過,用code換取access_token
try
{
result = OAuthApi.GetAccessToken(AppId, AppSecret, code);
}
catch (Exception ex)
{
return Content(ex.Message);
}
if (result.errcode != ReturnCode.請求成功)
{
return Content( "錯誤:" + result.errmsg);
}
//下麵2個數據也可以自己封裝成一個類,儲存在資料庫中(建議結合緩存)
//如果可以確保全全,可以將access_token存入用戶的cookie中,每一個人的access_token是不一樣的
HttpContext.Session.SetString( "OAuthAccessTokenStartTime" , DateTime.Now.ToString());
HttpContext.Session.SetString( "OAuthAccessToken" , result.ToJson());
//因為第一步選擇的是OAuthScope.snsapi_userinfo,這裡可以進一步獲取用戶詳細信息
try
{
if (! string .IsNullOrEmpty(returnUrl))
{
return Redirect(returnUrl);
}
OAuthUserInfo userInfo = OAuthApi.GetUserInfo(result.access_token, result.openid);
return View(userInfo);
}
catch (ErrorJsonResultException ex)
{
return Content(ex.Message);
}
}
|
//建議將result存入資料庫中,確保值訪問一次