我们知道openid是微信用户验证的重要标识,支付功能严重依赖这个东西,之前我们做微信支付的时候是通过在微信客户端直接调用官方接口,通过传code参数来调用,下面这样
getOpenId(){ //获取用户的openid let _this=this; wx.login({ success(res) { if (res.code) { // 发起网络请求 wx.request({ url: 'https://api.weixin.qq.com/sns/jscode2session', data: { appid:appId, //开发者appid secret:secret, //开发者AppSecret(小程序密钥) grant_type:"authorization_code", //默认authorization_code js_code: res.code //wx.login登录获取的code值 }, success(res) { _this.userinfo.openid=res.data.openid; _this.userinfo.session_key=res.data.session_key; } }) } else { console.log('登录失败!' + res.errMsg) } } }) } 复制代码
这样做理论上也可以拿到openid,但是这里有一个神坑,就是在小程序开发者工具直接测试,使用真机调试,都没有任何问题,但是一旦上传代码,使用小程序的体验版测试的话,就拿不到openid,奇怪的是,如果在体验版开启调试模式,又可以拿到,这是一个非常脑残的问题,直接影响就是开发环境和生产环境在代码相同的情况下,体现的效果不一样,微信官方也没有任何合理解释,经过很长时间的查找资料,获取openid不能直接在微信客户端来获取,应该改用后端来获取openid然后再返回给前端。
所以应该用Django来获取openid
def getopenid(request): res = {} appId = request.GET.get('appId')#开发者appid secret = request.GET.get('secret')#开发者AppSecret(小程序密钥) grant_type = "authorization_code" #默认authorization_code js_code = request.GET.get('js_code')#wx.login登录获取的code值 data = {'appId':appId,'secret':secret,"grant_type":grant_type,"js_code":js_code} url = "https://api.weixin.qq.com/sns/jscode2session" jscode = requests.get(url,data) res = jscode.json() return JsonResponse(res,safe=False,json_dumps_params={'ensure_ascii':False}) 复制代码
而前端获取openid的方法改造成请求本地接口
getOpenId(){ //获取用户的openid let _this=this; wx.login({ success(res) { if (res.code) { // 发起网络请求,改造成请求本地接口获取openid,规避体验版获取不到的问题 wx.request({ url: 'http://localhost:8000/getopenid', data: { appid:appId, //开发者appid secret:secret, //开发者AppSecret(小程序密钥) grant_type:"authorization_code", //默认authorization_code js_code: res.code //wx.login登录获取的code值 }, success(res) { _this.userinfo.openid=res.data.openid; _this.userinfo.session_key=res.data.session_key; } }) } else { console.log('登录失败!' + res.errMsg) } } }) } 复制代码
至此才解决了这个问题,这件事情说明一个问题,就是做任何事情都不能想当然,同时开发小程序的时候,真机测试没有问题并不代表没有问题,一定要到生产环境测一下,另外最后一个忠告,微信小程序获取openid一定要在server端获取再返回给前端,千万不要图省事在前端直接获取openid