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


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 相关文章推荐
javascript 小型动画组件与实现代码
Jun 02 PHP
CURL状态码列表(详细)
Jun 27 PHP
Zend Studio 实用快捷键一览表(精心整理)
Aug 10 PHP
CMS中PHP判断系统是否已经安装的方法示例
Jul 26 PHP
php json_encode()函数返回json数据实例代码
Oct 10 PHP
自编函数解决pathinfo()函数处理中文问题
Nov 03 PHP
php利用反射实现插件机制的方法
Mar 14 PHP
WordPres对前端页面调试时的两个PHP函数使用小技巧
Dec 22 PHP
php 防止表单重复提交两种实现方法
Nov 03 PHP
yii2.0整合阿里云oss的示例代码
Sep 19 PHP
PHP文件类型检查及fileinfo模块安装使用详解
May 09 PHP
thinkphp框架无限级栏目的排序功能实现方法示例
Mar 29 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
解析用PHP读写音频文件信息的详解(支持WMA和MP3)
2013/05/10 PHP
在wamp集成环境下升级php版本(实现方法)
2013/07/01 PHP
Yii2框架实现登陆添加验证码功能示例
2018/07/12 PHP
PHP消息队列实现及应用详解【队列处理订单系统和配送系统】
2019/05/20 PHP
(转载)JavaScript中匿名函数,函数直接量和闭包
2007/05/08 Javascript
利用js跨页面保存变量做菜单的方法
2008/01/17 Javascript
js 对联广告、漂浮广告封装类(IE,FF,Opera,Safari,Chrome
2009/11/26 Javascript
window.js 主要包含了页面的一些操作
2009/12/23 Javascript
jQuery News Ticker 基于jQuery的即时新闻行情展示插件
2011/11/05 Javascript
js面向对象之常见创建对象的几种方式(工厂模式、构造函数模式、原型模式)
2015/11/09 Javascript
Angular懒加载机制刷新后无法回退的快速解决方法
2016/08/30 Javascript
JS查找字符串中出现最多的字符及个数统计
2017/02/04 Javascript
JS简单获取当前年月日星期的方法示例
2017/02/07 Javascript
BootStrap select2 动态改变值的方法
2017/02/10 Javascript
js导出Excel表格超出26位英文字符的解决方法ES6
2017/11/15 Javascript
JS实现判断图片是否加载完成的方法分析
2018/07/31 Javascript
[01:06:39]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#1Liquid VS Alliance第三局
2016/03/02 DOTA
Python远程桌面协议RDPY安装使用介绍
2015/04/15 Python
Python首次安装后运行报错(0xc000007b)的解决方法
2016/10/18 Python
Python科学画图代码分享
2017/11/29 Python
Linux下python3.7.0安装教程
2018/07/30 Python
浅谈Python中的全局锁(GIL)问题
2019/01/11 Python
Python字符编码转码之GBK,UTF8互转
2020/02/09 Python
python框架Django实战商城项目之工程搭建过程图文详解
2020/03/09 Python
为什么说python更适合树莓派编程
2020/07/20 Python
华为python面试题
2016/05/03 面试题
法学专业本科生自荐信范文
2013/12/17 职场文书
新驾驶员个人自我评价
2014/01/03 职场文书
《再别康桥》教学反思
2014/02/12 职场文书
寒假家长评语大全
2014/04/16 职场文书
初中优秀班集体申报材料
2014/05/01 职场文书
中学生学习保证书
2015/02/26 职场文书
推荐信范文大全
2015/03/27 职场文书
SpringBoot 集成Redis 过程
2021/06/02 Redis
MySQL8.0的WITH查询详情
2021/08/30 MySQL
SQL优化老出错,那是你没弄明白MySQL解释计划用法
2021/11/27 MySQL