微信受權錯誤:"errcode":40163,"errmsg":"codebeenused 微信受權錯誤:"errcode":40163,"errmsg":"codebeenused

轉自:微信受權錯誤:"errcode":40163,"errmsg":"codebeenused

 

微信網頁受權獲取code值回調兩次的問題

1.說是域名緣由,目前未測試,沒有正確的域名html

  1. 問題描述:在調用微信網頁受權獲取openid值時,先獲取的code值,可是code值的接口 會走兩次回調。而code在6分鐘內只能用一次,因此處出現code失效的問題,問題顯示錯誤碼:{‘errcode’:40029,’errmsg’:’invalid code, hints: [ req_id: 0407ns44 ]’}
  2. 解決辦法: 出現這個問題是由於域名的問題,本人先使用的花生殼的內網穿透,可是花生殼的免費域名應用的是第三方代理域名,因此在向微信服務器發送請求的時候,微信回調時,會認爲你的域名請求不一致,會回調兩次,重定向你的服務器兩次,只需更改正式域名便可。就會回調一次。(網上說的返回值結束二次回調,和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 );

  最終網址結果api

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存入數據庫中,確保值訪問一次安全

相關文章
相關標籤/搜索