如何解决微信扫码登录网站不再返回客户详细信息的问题

从2022年6月20号开始,企微API对于某些字段的返回策略进行了调整,不再默认返回头像、性别、手机等敏感信息。所以在开发企业微信扫码登录Web应用时,我们只能通过企微API获取用户ID(user_id),而头像、电话等敏感信息无法直接通过扫码API获取。

为了获取这些详细信息,我们需要通过OAuth2授权流程来获取用户的授权。

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

 第一步,构建二维码

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

https://open.weixin.qq.com/connect/oauth2/authorize?appid=YOUR_APPID&redirect_uri=YOUR_REDIRECT_URI&response_type=code&scope=snsapi_base#wechat_redirect 

前端可以使用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');
        //错误处理逻辑
    }
}

第二步,等待扫码,接收Auth Code

在渲染二维码成功后,紧接着向后端发起一个HTTP请求waitForAuthCode,等待扫码的结果。这一步的作用是将Auth Code引人前端。企微手机端扫码后,手机直接向open.weixin.qq.com发起认证请求,微信认证服务器生成authcode成功后,它会重定向到redirect_uri指向的服务器,也就是我们自己的应用服务器。应用服务器对于这一重定向的响应回到手机端,手机端的这个页面响应可以设计成一个让客户确认的交互。可见,扫码这个过程中,没有数据再回到浏览器,那么就需要浏览器有一个获取Code的机制。

应用服务器已经在这一步获得了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)
请求地址:https://qyapi.weixin.qq.com/cgi-bin/auth/getuserinfo?access_token=ACCESS_TOKEN&code=CODE
参数说明:

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

正确返回: 

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

第四步,获取用户敏感信息

请求方式:POST(HTTPS)
请求地址:https://qyapi.weixin.qq.com/cgi-bin/auth/getuserdetail?access_token=ACCESS_TOKEN

请求包体:

{
   "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"
}

 最后,附上顺序图:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值