微信网页授权获取code值回调两次的问题
1.说是域名原因,目前未测试,没有正确的域名
- 问题描述:在调用微信网页授权获取openid值时,先获取的code值,但是code值的接口 会走两次回调。而code在6分钟内只能用一次,所以处出现code失效的问题,问题显示错误码:{‘errcode’:40029,’errmsg’:’invalid code, hints: [ req_id: 0407ns44 ]’}
- 解决办法: 出现这个问题是因为域名的问题,本人先使用的花生壳的内网穿透,但是花生壳的免费域名应用的是第三方代理域名,所以在向微信服务器发送请求的时候,微信回调时,会认为你的域名请求不一致,会回调两次,重定向你的服务器两次,只需更改正式域名即可。就会回调一次。(网上说的返回值结束二次回调,和301重定向 都是坑人的,折腾一天还是域名问题
2.说需要一个参数 &connect_redirect=1,这个是解决40029的错误
1 //实际使用生成url的代码 <br>string UrlUserInfo = OAuthApi.GetAuthorizeUrl(AppId, 2 "http://2a20h48668.imwork.net/weixin/UserInfoCallback?returnUrl=" + returnUrl.UrlEncode(), 3 state, OAuthScope.snsapi_userinfo); 4 // 摘要: 5 // 获取验证地址的API,以及参数说明 6 // 7 // 参数: 8 // appId: 9 // 公众号的唯一标识 10 // 11 // redirectUrl: 12 // 授权后重定向的回调链接地址,请使用urlencode对链接进行处理 13 // 14 // state: 15 // 重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节 16 // 17 // scope: 18 // 应用授权作用域,snsapi_base (不弹出授权页面,直接跳转,只能获取用户openid),snsapi_userinfo (弹出授权页面,可通过openid拿到昵称、性别、所在地。并且,即使在未关注的情况下,只要用户授权,也能获取其信息) 19 // 20 // responseType: 21 // 返回类型,请填写code(或保留默认) 22 // 23 // addConnectRedirect: 24 // 加上后可以解决40029-invalid code的问题(测试中) 25 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 /// <summary> 2 /// OAuthScope.snsapi_userinfo方式回调 3 /// </summary> 4 /// <param name="code"></param> 5 /// <param name="state"></param> 6 /// <param name="returnUrl">用户最初尝试进入的页面</param> 7 /// <returns></returns> 8 public ActionResult UserInfoCallback(string code, string state, string returnUrl) 9 { 10 if (string.IsNullOrEmpty(code)) 11 { 12 return Content("您拒绝了授权!"); 13 } 14 var orginState = data.getState(); 15 16 if (state != orginState) 17 { 18 //这里的state其实是会暴露给客户端的,验证能力很弱,这里只是演示一下, 19 //建议用完之后就清空,将其一次性使用 20 //实际上可以存任何想传递的数据,比如用户ID,并且需要结合例如下面的Session["OAuthAccessToken"]进行验证 21 return Content("验证失败!请从正规途径进入!"); 22 } 23 24 OAuthAccessTokenResult result = null; 25 26 //通过,用code换取access_token 27 try 28 { 29 result = OAuthApi.GetAccessToken(AppId, AppSecret, code); 30 } 31 catch (Exception ex) 32 { 33 return Content(ex.Message); 34 } 35 if (result.errcode != ReturnCode.请求成功) 36 { 37 return Content("错误:" + result.errmsg); 38 } 39 //下面2个数据也可以自己封装成一个类,储存在数据库中(建议结合缓存) 40 //如果可以确保安全,可以将access_token存入用户的cookie中,每一个人的access_token是不一样的 41 HttpContext.Session.SetString("OAuthAccessTokenStartTime", DateTime.Now.ToString()); 42 HttpContext.Session.SetString("OAuthAccessToken", result.ToJson()); 43 44 //因为第一步选择的是OAuthScope.snsapi_userinfo,这里可以进一步获取用户详细信息 45 try 46 { 47 if (!string.IsNullOrEmpty(returnUrl)) 48 { 49 return Redirect(returnUrl); 50 } 51 52 OAuthUserInfo userInfo = OAuthApi.GetUserInfo(result.access_token, result.openid); 53 return View(userInfo); 54 } 55 catch (ErrorJsonResultException ex) 56 { 57 return Content(ex.Message); 58 } 59 }
//建议将result存入数据库中,确保值访问一次