[关闭]
@ronaldoooo 2016-09-12T08:11:40.000000Z 字数 996 阅读 792

9.12 wechat2.1版本分析记录

为什么第一次点会挂

用户第一次手动点击页面,跳转入授权页。此时scope填'snsapi_userinfo,snsapi_base',此时由于微信端的处理
image_1aselctdc30brqn195h13ot16e528.png-10.2kB
这一句是通过code换取access_token返回的scope为snsapi_userinfo(不知为何仅返回其一),所以在获取$user的逻辑
image_1asel9qus1hjl1bog1jror17mul1r.png-39.2kB
中就进入了else执行,返回$user
pic1-userinfo.png-104.3kB
这里$user是通过userinfo接口得到的信息,并没有access_token,所以报了那个错。

为什么第二次点不挂

用户第二次点击,跳转入授权页。此时scope同上,填的也是'snsapi_userinfo,snsapi_base',但不同的是这一句
image_1aselctdc30brqn195h13ot16e528.png-10.2kB
由于用户刚刚手动授权过,此时不用用户点击微信自动授权。(但可以看到一个页面跳转)。此时微信返回的scope居然是'snsapi_base,snsapi_userinfo'.......所以
image_1asel9qus1hjl1bog1jror17mul1r.png-39.2kB
这里152行判断是true,直接把permission接口的数据当作$user返回了....打印出来就是
pic-userinfo-and-base.png-126.5kB
那么可以发现这里返回的并不是实际的$user信息。。需要用
image_1asem1f78vfm1b4u10kbi9n18sc32.png-16.7kB
来再手动调一次接口,获取实际的用户信息。这也就是为什么第二次不会报错。

分析

可以看出,微信在对scope'snsapi_base,snsapi_userinfo'的这种混合模式行为是非常模糊的,文档上并没有交代可以或者禁止这么做。我当时这么写的原因可能也只是为了中和几种不通的场景以适应平稳变迁(可能一开始只是base就够了,后来又要加上userinfo)。
包括wechat作者本人可能也没有意识到这种做法,
image_1asel9qus1hjl1bog1jror17mul1r.png-39.2kB
152行可以看出,他本意是如果scope!=snsapi_userinfo,那么就一定是snsapi_base,这时是不需要获取到用户数据的,所以直接就把permission接口获取的基本信息返回了。
这里条件判断如果写成
image_1asemst6g1q4j13j99oq42q1bbd3f.png-13kB
就不会出现这种问题。

总结

  1. 避免用'snsapi_base,snsapi_userinfo'的混合scope。要么都用userinfo,要么就根据不同场景做不同的授权逻辑。
  2. 对于微信的redirect,尽量使用固定的回调地址,把用户想要访问的页面地址(next_url)放入session中,在回调地址中统一处理。这样在debug的时候相对比较干净。我看了下wechat3.0也是推荐这么做。
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注