微信扫码不再返回客户手机等详细信息怎么办

149 阅读3分钟

 在开发企业微信扫码Web应用时,你可能遇到只能通过企微API获取用户ID(user_id),而头像、电话等敏感信息无法直接通过扫码API获取的问题。这是由企业微信API的更新策略导致的。从2022年6月20号开始,企微API对于某些字段的返回策略进行了调整,不再默认返回头像、性别、手机等敏感信息。为了获取这些详细信息,我们需要通过OAuth2授权流程来获取用户的授权。

如果通过OAuth2获取用户详细,那么就不能跳转到@wecom-jssdk提供的扫码页面或者嵌入企微API生成的二维码。这需要自己构建登录二维码。

 

 OAuth2授权URL的格式如下,将这个链接文字构建为二维码,用以客户手机扫码。

open.weixin.qq.com/connect/oau…

前端可以使用qrious.js库构造二维码。也可以在后端渲染。

前端代码示例:

async function refreshqrcode(){
    try{
        res=await fetch('/qregain');
        if(res.ok){
            const { state } = await res.json();
            //state的内容由后端生成,可以包含用来识别客户端的信息和其他内容,微信auth服务器会原样转发
            url='https://open.weixin.qq.com/connect/oauth2/authorize?';
            qrtext=url+'appid={{data.appid}}&redirect_uri='+encodeURIComponent('{{data.redirect_uri}}')+'&response_type=code&scope=snsapi_privateinfo&state='+state+'&agentid={{data.agentid}}#wechat_redirect';
            //双大括号是Jinja模板中表示插入变量的方式,js用`${}`
            //scope=snsapi_privateinfo表示获取用户敏感信息
            qrElement.parentNode.style.opacity='1.0';
            //设置二维码img元素的父元素透明度为1.0,失效时=0.2
            
            var qr = new QRious({
                element: qrElement,
                size:300,
                value: qrtext
            });//qriors.js库的用法
        }
        else{
            consoloe.log(res.status);
        }
    }catch(error){
        console.log('err');
    }
}

在渲染二维码成功后,紧接着向后端发起一个HTTP请求waitForAuthCode,等待扫码的结果。这一步的作用是:企微手机端扫码后,实际上是手机向open.weixin.qq.com发起认证请求,微信认证服务器生成authcode成功后,它会重定向到redirect_uri指向的服务器,也就是我们自己的应用服务器。应用服务器的对于这一重定向的响应会回到手机端。可以把这个页面响应设计成一个让客户确认的页面。

应用服务器已经在这一步获得了authcode,可以在设定的超时范围内将authcode响应给前端的waitForAuthCode。前端:

    async function waitForAuthCode() {
        try {
            const response = await fetch('/waitauthcode');
            if (response.ok) {
                const { authCode } = await response.json();
                scanover=true;
                window.location.href = 'https://example.com/signin?code='+authCode;
                //取得authcode后,请求登录验证
            }
           
        }catch (error) {
            //超时,刷新二维码
            console.error('Error waiting for auth code:', error);
            refreshqrcode();
        }
    }

后端以Flask为例:

import queue

@app.route('/waitauthcode') 
def _check_code(*args):
"""
微信auth服务器返回的authcode进入以客户uid命名的队列globals()[uid]

"""
    uid=request.cookies.get('uid')
    q=globals()[uid]
    try:
        code=q.get(timeout=60) #取得authcode
        return jsonify({'authCode': auth_code})
    except:
        q=None #超时的处理
        return jsonify({'error': 'Timeout waiting for auth code'}), 408
    

前端带code和state参数向应用服务器发起登录请求。服务器收到请求后, 请求获取用户身份。注意:auth code只能使用一次,所以后端必须有控制逻辑。

请求方式: GET(HTTPS
请求地址: qyapi.weixin.qq.com/cgi-bin/aut…
参数说明:

参数必须说明
access_token调用接口凭证
code通过成员授权获取到的code,最大为512字节。每次成员授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。

正确返回: 

{
"errcode": 0,
"errmsg": "ok",
"userid":"USERID",
"user_ticket": "USER_TICKET"
}

获取用户敏感信息:

请求方式: POST(HTTPS
请求地址: qyapi.weixin.qq.com/cgi-bin/aut…

请求包体:

{
   "user_ticket": "USER_TICKET"
}

正确的返回结果: 

{
  "avatar": "https://wework.qpic.cn/wwpic3az/63*****9/0",
  "email": "someone@mail.qq.com",
  "errcode": 0,
  "errmsg": "ok",
  "gender": "0",
  "mobile": "1********00",
  "name": "\u****\u****",
  "qr_code": "https://open.work.weixin.qq.com/wwopen/userQRCode?vcode=vcac*****d",
  "userid": "001"
}

 最后,附上顺序图:​编辑