小程序审核突然没通过,理由如下:
这个问题开发过程中自己确实遇到过,几率性的,一般第一次不行,第二次肯定可以了,但是不是一开始写小程序就有的,不知道什么时候开始就这样了,验证的逻辑都是按照官方的,从来没有改变过。然后上社区一搜,很多类似的问题,如下图所示。
看了下这个问题,第一次验证签名如下:
小程序端通过wx.login成功后获取的code
rawdata,这个我都是同一用户登录,前后信息没啥变化
通过1中的code,后端调用api获得的session data,其中openid肯定同一用户每次也都一样的,session_key如果过期,那么第一次和第二次理论应该是不一样的。(但实际情况前后两次是一致的,具体可参见下图)
小程序端获取到的用户的签名
后端通过session key校验出来的签名。
很明显,4和5不一致,校验失败。接下来是第二次交验:
还是同样的逻辑顺序。
小程序端通过wx.login成功后获取的code。很明显,code跟第一次是不一样的,另外根据官方文档描述,因为又重新调用了wx.login,会导致session_key过期。(这似乎说明code发生变化也是对的,因为按推测,seesionkey应该也发生了变化,否则怎么叫“被更新”)请看下图官方文档说明:
rawdata,这个我都是同一用户登录,前后信息没啥变化
根据1中的官方描述,奇怪的现象就发生了,在后端根据新的code,获取的session data,很明显session key还是第一次是一样的,也就是说,我重新调用了wx.login, code是变了,但是session key却和第一次保持一致的。
小程序端获取到的用户的签名
后端通过session key校验出来的签名。因为用的是同样的rawdata,同样的session key,所以两次校验的结果是一样的,但是第二次4中,小程序端获取的签名是跟此次校验结果是一致的。
所以问题就来了,这问题到底出在什么地方?似乎官方文档描述的就有问题,还是我本身的逻辑顺序有问题?请官方指教,谢谢。
我感觉目前getuserinfo的button存在bug,并不是session的问题
说下我的流程:
1、页面onload,里wx.checksession,fail了就wx.login,第一次打印log输出未过期
2、页面加载后立刻点击getUserInfo的button
3、getUserInfo的回调中,首先wx.login(这个实际上不需要,这里只是为了复现bug),获取code
4、发送code和button回调中的rawData和签名A到服务端
5、服务端验签失败,输入log中,sessionkey为A
6、立刻第二次点击(第二步),此时checksession依然输出未过期
7、发送新code和统一的rawData还有签名B到服务端,注意这里的签名B肯定跟刚才的签名A不一样
8、服务端验签成功,log中显示,sessionkey依然为A
第二次尝试,中间增加wx.getUserInfo:
1、页面onload,里wx.checksession,fail了就wx.login,第一次打印log输出未过期
2、页面加载后立刻点击getUserInfo的button
3、getUserInfo的回调中,首先wx.login(这个实际上不需要,这里只是为了复现bug),获取code
4、调用wx.getUserInfo,打印log,输出签名 W1
5、发送code和button回调中的rawData和签名A到服务端
6、服务端验签失败,输入log中,sessionkey为A
6、立刻第二次点击(第二步),此时checksession依然输出未过期
7、发送新code和统一的rawData还有签名B到服务端,注意这里的签名B肯定跟刚才的签名A不一样
8、调用wx.getUserInfo,打印log,注意输出签名仍为 W1
9、服务端验签成功,log中显示,sessionkey依然为A
结论是:
1、在一个生命周期内,多次调用wx.login并不会改变code换回来的sessionkey
2、在wx.login中,button和wx.getUserInfo返回的签名不同,但多次点击,每一次的button和button是一样的,wx.getUserInfo和wx.getUserInfo也是一样的,但是一小段时间后,就都会换新的签名了
3、但是2中有个问题,如果页面刷新,过一会点击,这时候button返回的签名是无效的,wx.getUserInfo是有效的!再次点击,button的签名换了(这时候是有效的),wx.getUserInfo的签名没变,这时候也是有效的
4、最简单的处理办法是button回调里面再调wx.getUserInfo一次,用wx.getUserInfo的信息去请求服务端,此方式比较繁琐但没有任何问题
具体还要看官方人员排查,开发者也要维护要checksession和wx.login,不要频繁login
为什么我一个米大师应用名称同步的问题,上礼拜五到现在都没人可以帮我们解决呢? 在这里却看到了3个不同名字的官方人员。。真心求助
小游戏改名后,米大师中应用名称不能同步,求协助
问题模块 | 框架类型 | 问题类型 | 操作时间 | AppID |
---|---|---|---|---|
管理后台 | 小游戏 | Bug | 昨天 00:00 | wx0c9ea6721d1da882 |
- 当前 Bug 的表现(可附上截图)
小程序改名后,米大师中应用名称不能同步,求协助,着急
appid:wx0c9ea6721d1da882
code 的作用只是用来换取 session_key,从你提供的信息来看,不会是 code 的问题,只可能是 session_key 的问题。有个问题需要注意:
验签使用的 session_key,必须和小程序端获取到的签名是配对。因此这里需要你确认下,获取 3 和 4 的时序关系是怎样的?预期应该是这样的逻辑:
获取 3(wx.login + jscode2session 拿到 session_key)
获取 4(wx.getUserInfo 拿到 signature)
使用 1、2 拿到的结果来验签
如果你的服务器缓存了 session_key,在 session_key 未过期的情况下(可用 wx.checkSession 确认),可以跳过 1 。假设你用的是很久以前拿到的 signature + 刚获取到的 session_key 来验签,那就有可能不通过。
参考流程代码
authPromise = new Promise(async (resolve, reject) => { while (!authorization.token) { try { const data = await WXP.login(); let res; try { if (canAutoLogin) { res = await getToken(data.code); } else { throw Error( 'try user info' ); } } catch (e) { canAutoLogin = false ; const set = await WXP.getSetting(); if (!set.authSetting[ 'scope.userInfo' ]) { throw Error( 'scope userInfo disabled' ); } const user = await WXP.getUserInfo({ withCredentials: true , lang: 'zh_CN' , }); // [@todo](/user/todo) 换 token 的时候出现了错误需要处理 try { res = await getToken(data.code, user.iv, user.encryptedData); } catch (err) { throw err; } } authorization.token = res.data.access_token; authPromise = null ; // 顺便获取一次 store.dispatch( 'user/USER_GET_PROFILE' ) resolve(); } catch (e) { const set = await WXP.getSetting(); const router = Vue.prototype.$router; if (!set.authSetting[ 'scope.userInfo' ]) { router.push( '/pages/user/login' ); try { await new Promise((res, rej) => { Vue.bus.on( 'ON_USER_LOGIN' , (action, data) => { if (action === true ) { res(data); } else { rej(); } }); }); } catch (err) { // 暂时先什么都不做 用户必须授权 // authPromise = null; // reject(err); // throw err; } Vue.bus.off( 'ON_USER_LOGIN' ) } } } }); |
谢谢您这么及时的回答问题,我姑且认为是回答。首先这个发帖人我完全不认识,所以说明这个问题似乎不需要定向来排查吧?很多不一样的开发者都遇到了相同的问题,当然不说100%排除是我们这些人犯了同样的错误,我希望也是我们犯了错,因为毕竟你们比我们牛,几乎不会出错,而且我们错了更容易改,对吧?另外你们在提供这些相对敏感的信息时候,有保密的文本吗?直接贴在公开的论坛里让别人看到appid和openid?虽然这不是secret,但总感觉有点怪怪得啊,一般其他平台,提供这些敏感信息,都是有保密的字段可以填写的,只有你们官方可以看到,不是吗?另外既然您说了要appid,那我这正好有2个,我想说的是这2个都同时有这个问题。另外我比较弱鸡,还是请麻烦解答下,直接这么公开的提供appid和openid没啥安全隐患吧?再次感谢您专业的帮助。
wx345ace1cb60e9fdf
wxaa0ddc4b1f7e3156
o_WKt4rN6LTl6aQR2Fb9ax_35zZU