redirect_uri域名与后台配置不一致,错误码:10003,如图所示:
前端访问域名为:uc.test.com
后端2台服务器,域名均为:uc2.test.com
反代请求浏览大致如下:
浏览器 -> 前端服务器(https://uc.test.com/) -> 反代 -> 后端服务器(https://uc2.test.com/)
如果不做反代负载均衡的话,就不会报这个错误,这是为什么呢?
原因分析
首先得看看微信的登录验证时序图:
上图来自:
网站应用微信登录开发指南
但是这个问题其实和这个时序图没什么关系,因为使用 Fiddler 抓包发现:
访问:
http://uc.test.com/ 时,会 302 跳转到:
http://uc.test.com/logins/wxlogin?state=http://uc.test.com/index/index/Wxloginback?c=&ser=&p=&vc=
再次 302 跳转到:
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=http%3A%2F%2Fuc2.test.com%2Flogins%2Fwxlogin&response_type=code&...
报错的正是此处的
redirect_uri=http%3A%2F%2Fuc2.test.com%2Flogins%2Fwxlogin,URLDecode后为:
http://uc2.test.com/logins/wxlogin
而以上2次跳转,均是由后端服务器控制的,因此问题还是在后端服务器上部署的程序上。
当不使用负载均衡时,不会报这个错误,这是因为后端服务器输出的就是
redirect_uri=http://uc.test.com/logins/wxlogin。
但是当使用负载均衡后,为什么后端服务器会输出
redirect_uri=http://uc2.test.com/logins/wxlogin?
很明显,这是 PHP 程序控制的。
解决方法
一、改程序代码
目前碰到的这个客户,后端是PHP写的程序,全局搜索后发现以下代码:
if(!isset($_GET['code'])){
//以下信息可安放在用户登录界面上:
$posturl= 'https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appid.'&redirect_uri='.$hostUrl.'&response_type=code&scope=snsapi_base&state='.$state.'#wechat_redirect';
header('Location:'.$posturl);//跳转到第三方登录入口
exit;
}
很明显,redirect_uri 值中的 $hostUrl 是返回了后端服务器自己的域名,即 uc2.test.com。
由于这款 PHP 程序是使用 ThinkPHP 开发的,我们很容易就找到了它的配置文件:
userCenter/application/config.php (具体路径,根据你使用的程序会有所不同)
打开配置文件,将域名根 url_domain_root 设置为前端访问的域名,如下:
// 域名根,如thinkphp.cn
'url_domain_root' => 'uc.test.com',
二、调整nginx配置
将所有后端服务器上的网站域名都设置为 uc.test.com。
这是比较科学的解决方法,但是由于客户的前端做 Nginx 反代的机器上也充当了后端服务器的角色,uc.test.com 已经分配给前端反代网站使用,后端网站不能再使用 uc2.test.com。因此只能使用方法一来解决。