解决微信授权回调页面域名只能设置一个的问题


Posted in PHP onDecember 11, 2016

最终的解决方案是:https://github.com/liuyunzhuge/php_weixin_proxy,详细的介绍请往下阅读。

在做项目集成微信登录以及微信支付的时候,都需要进行用户授权。这个授权的流程可以简单描述为:

1. 用户从我们的应用触发需要授权的操作,比如点击微信登录;

2. 应用收到这种用户请求后,将用户重定向到微信提供的一个授权页面:

解决微信授权回调页面域名只能设置一个的问题解决微信授权回调页面域名只能设置一个的问题

3. 用户通过微信扫码(PC端授权,上边左图)或者点击确认按钮(移动端授权,上边右图)告知微信,授权应用访问自己的微信账号信息;

4. 微信收到用户的授权许可后,生成授权码,并把它作为参数回调至应用的某个页面;

5. 应用的回调页面在接收到微信的回调请求后,拿到其中的授权码,并通过微信官方提供的access token api接口获取access token;

6. 最后通过access token以及微信官方提供的另一个userinfo api接口就能获取到用户的微信账号信息。

为了实现这个过程,首先要为应用申请一个微信公众号,并将应用最终部署的域名设置到微信公众号设置里面的授权回调页面域名这个选项里面。微信官方对这个选项的说明如下:

关于网页授权回调域名的说明

1、在微信公众号请求用户网页授权之前,开发者需要先到公众平台官网中的“开发 - 接口权限 - 网页服务 - 网页帐号 - 网页授权获取用户基本信息”的配置选项中,修改授权回调域名。请注意,这里填写的是域名(是一个字符串),而不是URL,因此请勿加 http:// 等协议头;

2、授权回调域名配置规范为全域名,比如需要网页授权的域名为:www.qq.com,配置以后此域名下面的页面http://www.qq.com/music.html 、 http://www.qq.com/login.html 都可以进行OAuth2.0鉴权。但http://pay.qq.com 、 http://music.qq.com 、 http://qq.com无法进行OAuth2.0鉴权

3、如果公众号登录授权给了第三方开发者来进行管理,则不必做任何设置,由第三方代替公众号实现网页授权即可

由此可见,这个规则极其严格。如果说我们的应用最终部署的时候只有一个域名,那么这种规则不会有什么问题;但是考虑到将来应用的复杂性,我们可能在应用设计之初就会对应用做拆分,然后不同的业务采用不同的二级域名来部署。比如一个带有交易的应用,你可能会把登录注册,交易管理和常规业务都独立出来,然后采用以下的方式来部署它们:

www.your.com 部署常规业务;

trade.your.com 部署交易管理的业务;

passport.your.com 部署登录注册的业务;

在这种模式下,如果集成微信登录和微信支付,前面说的授权回调页面域名的规则就会给应用带来问题。在这里:至少可以确认trade.your.com和passport.your.com都需要前面的介绍的用户微信授权,但是它们是两个不同的子域名,而且我们只有一个公众号;根据授权回调页面域名的原则,它只能用一个域名,并且只有回调地址的域名与该设置完全相同,才能成功发起微信授权,否则就会提示rediret_uri参数错误或者引发无法回调的问题。

那么这种情况该如何处理?

当下的解决方案是引入一个新的非常简单的应用来作为微信授权的代理服务,可以这么做:

1. 把公众号的网页授权接口域名设置成另外一个子域名,如proxy.your.com;

2. 然后把php_weixin_proxy里面的index.php部署到proxy.your.com

php_weixin_proxy下的index.php是一个很简单的php文件,你可以直接查看源码了解它的实现方式。因为当前项目的环境,我采用php来完成这个代理服务实现,实际上,你完全可以用任意平台语言来完成类似的功能。

当其它业务需要发起微信授权时,将授权请求先发到proxy.your.com,然后proxy.your.com会把这个请求转发到微信;

当用户同意授权后,proxy.your.com会收到微信的授权回调,并把回调结果(code、state参数)原封不动地再返回给最开始发起授权的业务。

唯一的区别在于,在不使用proxy.your.com的时候,你从应用发起微信授权的链接应该是这样的:

https://open.weixin.qq.com/connect/qrconnect?appid=xxxxx&redirect_uri=http%3A%2F%2Fpassport.your.com%2F&response_type=code&scope=snsapi_login&state=584bc87e11ff37492#wechat_redirect

用了proxy.your.com之后,这个授权链接就应该是这样的:

http://proxy.your.com/?appid=xxxxx&redirect_uri=http%3A%2F%2Fpassport.your.com%2Flogin%2Fnotify&response_type=code&scope=snsapi_base&state=584bc87e11ff37492&device=pc

后面这个链接跟上面的比:

1. 后面的链接中的host变成了proxy.your.com,也就是代理的授权回调域名;

2. 后面的多了一个device参数,这个是必要的。因为微信pc端跟移动端的授权地址是不一样的,而后面的链接是发送个proxy.your.com的,所以需要多加个参数告诉它在转发给授权申请给微信的时候,是用PC端还是移动端的授权地址。

解决微信授权回调页面域名只能设置一个的问题

整体方案思路:

解决微信授权回调页面域名只能设置一个的问题

小结:

这个方案我测试过,是行的通的。虽然说引入了代理服务,增加了一次重定向操作,不过由于这个授权请求并不是所有请求都需要,所以实际上也不会对用户体验产生多大的影响,但是从架构上来说,它的好处很明显,能够配合着应用的拆分逻辑,集成同一个公众号的登录及支付功能,不必为每个子应用都单独申请一个公众号来开发了(这种方式从业务上来说也不合理,一个公司哪需要运营那么多公众号)。

以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,同时也希望多多支持三水点靠木!

PHP 相关文章推荐
PHP生成网页快照 不用COM不用扩展.
Feb 11 PHP
备份mysql数据库的php代码(一个表一个文件)
May 28 PHP
php中的一些数组排序方法分享
Jul 20 PHP
php实现utf-8转unicode函数分享
Jan 06 PHP
WordPress中Gravatar头像缓存到本地及相关优化的技巧
Dec 19 PHP
PHP微信API接口类
Aug 22 PHP
PHP内存缓存功能memcached示例
Oct 19 PHP
浅谈PHP表单提交(POST&GET&URL编/解码)
Apr 03 PHP
ThinkPHP中create()方法自动验证实例
Apr 26 PHP
PHP高效获取远程图片尺寸和大小的实现方法
Oct 20 PHP
Swoole源码中如何查询Websocket的连接问题详解
Aug 30 PHP
详解phpstorm2020最新破解方法
Sep 17 PHP
Zend Framework数据库操作方法实例总结
Dec 11 #PHP
smarty模板数学运算示例
Dec 11 #PHP
Zend Framework入门应用实例详解
Dec 11 #PHP
Zend Framework前端控制器用法示例
Dec 11 #PHP
Zend Framework路由器用法实例详解
Dec 11 #PHP
Zend Framework分发器用法示例
Dec 11 #PHP
PHP与SQL语句常用大全
Dec 10 #PHP
You might like
laravel框架实现后台登录、退出功能示例
2019/10/31 PHP
在视频前插入广告
2006/11/20 Javascript
jquery下组织javascript代码(js函数化)
2010/08/25 Javascript
XMLHTTP 乱码的解决方法(UTF8,GB2312 编码 解码)
2011/01/12 Javascript
js控制frameSet示例
2013/09/10 Javascript
jquery实现可自动判断位置的弹出层效果代码
2015/10/12 Javascript
快速掌握Node.js之Window下配置NodeJs环境
2016/03/21 NodeJs
JavaScript中split与join函数的进阶使用技巧
2016/05/03 Javascript
Vue 使用中的小技巧
2018/04/26 Javascript
vue将毫秒数转化为正常日期格式的实例
2018/09/16 Javascript
浅析JS中什么是自定义react数据验证组件
2018/10/19 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
2019/06/18 jQuery
详解js中的原型,原型对象,原型链
2020/07/16 Javascript
vue实现在进行增删改操作后刷新页面
2020/08/05 Javascript
一篇文章带你搞懂Vue虚拟Dom与diff算法
2020/08/25 Javascript
Python使用smtplib模块发送电子邮件的流程详解
2016/06/27 Python
python实现字符串连接的三种方法及其效率、适用场景详解
2017/01/13 Python
python读文件保存到字典,修改字典并写入新文件的实例
2018/04/23 Python
Python使用pyautogui模块实现自动化鼠标和键盘操作示例
2018/09/04 Python
Python WEB应用部署的实现方法
2019/01/02 Python
Python 中的参数传递、返回值、浅拷贝、深拷贝
2019/06/25 Python
使用Python做垃圾分类的原理及实例代码附源码
2019/07/02 Python
Pytorch反向求导更新网络参数的方法
2019/08/17 Python
解决TensorFlow GPU版出现OOM错误的问题
2020/02/03 Python
Python数据可视化处理库PyEcharts柱状图,饼图,线性图,词云图常用实例详解
2020/02/10 Python
python标准库OS模块函数列表与实例全解
2020/03/10 Python
Python通过两个dataframe用for循环求笛卡尔积
2020/04/29 Python
详解css3 Transition属性(平滑过渡菜单栏案例)
2017/09/05 HTML / CSS
美国手机支架公司:PopSockets
2019/11/27 全球购物
如何在Oracle中查看各个表、表空间占用空间的大小
2015/10/31 面试题
教师应聘个人求职信
2013/12/10 职场文书
小学班级口号
2014/06/09 职场文书
团队拓展活动方案
2014/08/28 职场文书
银行转正自我鉴定
2014/09/29 职场文书
2016简单的租房合同范本
2016/03/18 职场文书
SQL Server中的游标介绍
2022/05/20 SQL Server