收藏
回答

微信公众号网页授权登录有时回调很慢甚至收不到回调,该如何解决呢?

问题描述:

h5页面用户打开通过用户授权登录,多数情况下是能正常通过微信的回调页面获取到code并且进而获取用户的账户信息,不过通过分析日志发现有时候回调很慢,有时候回调地址没被调用,从而导致用户打开页面后一直空白。为了更清晰地描述问题,下面结合代码(php)和日志来进一步说明问题。

代码流程:

1、发起登录请求

protected function authorize($scope, $goto = '', $handler = 'LOGIN') {
    lf_performance(__LINE__, 'authorize');
    lf_log(lf_data($_SERVER, 'HTTP_USER_AGENT', 'HTTP_USER_AGENT'), 'error');
   
    ……
    $pass = [
        'goto' => $goto,
        'handler' => $handler,
        'partner' => input('param.partner', ''),
    ];

    //优先使用session, session失效cache弥补
    // Session::set('mp_intent', $pass);
    $key = lf_random_string(12);
    // Cache::set($key, $pass, 30);

    //url里直接传$pass是不行的,所以最开始都是用session传递数据的。不过有少部分人的手机会有问题,可能cookie的设置问题。
    //18-10-22发现可以使用http_build_query的方式进行传递,所以用此方法作为补充
    $para = [
        'appid' => config('mp.app_id'),
        'redirect_uri' => url('callback', null, config('URL_HTML_SUFFIX'), true) . '?' . http_build_query($pass),
        'response_type' => 'code',
        'scope' => $scope,
        'state' => $key
    ];
    $query = http_build_query($para);

    $url = "https://open.weixin.qq.com/connect/oauth2/authorize?{$query}#wechat_redirect";

    header("location:$url");
    exit(0);
}

代码中lf_performance()会记录文本日志,日志中会包含当时的毫秒级时间戳,便于分析速度问题。lf_log()也是用来记录日志的,这里记录了user_agent,都是为了分析这个问题加的。函数最后让浏览器跳转到https://open.weixin.qq.com/connect/oauth2/authorize,等待微信携带code的回调。

2、回调的处理

public function callback() {
    lf_performance(__LINE__, 'callback');
    $code = input('param.code');
    //var_dump($code);
    if (empty($code)) {
        lf_log("callback() called without code: $code", 'error');
        echo '微信登录授权失败';
        return;
    }

    $para = [
        'appid' => config('svc_fxw.app_id'),
        'secret' => config('svc_fxw.app_secret'),
        'code' => $code,
        'grant_type' => 'authorization_code'
    ];
    $query = http_build_query($para);
    $url = "https://api.weixin.qq.com/sns/oauth2/access_token?$query";

    $retData = lf_curl_get($url);
    $data = json_decode($retData, true);

    if (isset($data['scope']) && 'snsapi_userinfo' == $data['scope']) {
        //$data = $this->refreshToken($data);
        $data = $this->getUserInfo($data);
    }

    $this->ending($data);
}

这里只要被回调到,就会使用lf_performance()记录时间戳日志,然后完成用户信息的获取,最后调用ending()做登录后的处理。待会查看日志的时候,主要查看第一步中的authorize和这一步callback的lf_performance()日志,同一个ip是否成对出现,两者是时间差是否在1s以内。

3、登录后处理

protected function ending($data) {
     ……
    // print_r($data);
    if ($intent['goto']) {
        lf_performance(__LINE__, 'redirect');
        //调试错误时,此处注释掉不跳转即可
        $this->redirect($intent['goto']);
    }

    echo '没有指定目标地址';
    exit(0);
}

这一步对于本问题来说不是太涉及,为了完整性,也描述一下,就是完成用户数据的处理以后,跳转到用户希望打开的浏览页面($intend['goto']),并且通过lf_performance()记录redirect的时间戳日志。

代码流程已结束,下面分析日志:

[ 2020-08-14T13:49:03+08:00 ] 125.123.211.84 GET /ident-share-page.html?page=https%3A//www.dichanw.com/wap/housedetail/H354992496/share&handler=RELATION&method=userInfo&partner=FXWN8150&from=timeline
[ error ] authorize:366:1597384143.0132
[ error ] Mozilla/5.0 (Linux; Android 10; ELE-AL00 Build/HUAWEIELE-AL00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2577 MMWEBSDK/200701 Mobile Safari/537.36 MMWEBID/1666 MicroMessenger/7.0.17.1720(0x27001139) Process/toolsmp WeChat/arm64 NetType/WIFI Language/zh_CN ABI/arm64
---------------------------------------------------------------
[ 2020-08-14T13:49:04+08:00 ] 125.123.211.84 GET /ident-Share-callback.html?goto=https%3A%2F%2Fwww.dichanw.com%2Fwap%2Fhousedetail%2FH354992496%2Fshare&handler=RELATION&partner=FXWN8150&debug=&code=061ubY2003Qj8K16V6400SfOJy4ubY2r&state=hHo5nVZUnDMz
[ error ] callback:408:1597384143.5543
[ error ] redirect:577:1597384144.1615
---------------------------------------------------------------
[ 2020-08-14T13:49:07+08:00 ] 122.238.188.128 GET /ident-share-page.html?page=https%3A//www.dichanw.com/wap/news/detail%3F_id%3D137&handler=RELATION&method=userInfo&partner=NHVB7537
[ error ] authorize:366:1597384147.3108
[ error ] Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.14(0x17000e2e) NetType/WIFI Language/zh_CN
---------------------------------------------------------------
[ 2020-08-14T13:49:07+08:00 ] 113.214.206.15 GET /ident-share-page.html?page=https%3A//www.dichanw.com/wap/housedetail/H61964310/share&handler=RELATION&method=userInfo&partner=BQKV5456
[ error ] authorize:366:1597384147.9276
[ error ] Mozilla/5.0 (iPhone; CPU iPhone OS 12_4_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.14(0x17000e2e) NetType/WIFI Language/zh_CN
---------------------------------------------------------------
[ 2020-08-14T13:49:09+08:00 ] 112.17.247.143 GET /ident-share-page.html?page=https%3A//www.dichanw.com/wap/news/detail%3F_id%3D137&handler=RELATION&method=userInfo&partner=NHVB7537
[ error ] authorize:366:1597384149.3741
[ error ] Mozilla/5.0 (iPhone; CPU iPhone OS 13_4_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.14(0x17000e2e) NetType/4G Language/zh_CN
---------------------------------------------------------------
[ 2020-08-14T13:49:12+08:00 ] 106.33.13.206 GET /ident-share-page.html?page=https%3A//www.dichanw.com/wap/housedetail/H805174792/share&handler=RELATION&method=userInfo&partner=QQQP8997&from=timeline
[ error ] authorize:366:1597384152.762
[ error ] Mozilla/5.0 (Linux; Android 10; V2002A Build/QP1A.190711.020; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/78.0.3904.62 XWEB/2577 MMWEBSDK/200601 Mobile Safari/537.36 MMWEBID/1117 MicroMessenger/7.0.16.1700(0x2700103F) Process/toolsmp WeChat/arm64 NetType/4G Language/zh_CN ABI/arm64
---------------------------------------------------------------
[ 2020-08-14T13:49:13+08:00 ] 218.75.60.198 GET /ident-share-page.html?page=https%3A//www.dichanw.com/wap/housedetail/H614064154/share&handler=RELATION&method=userInfo&partner=WOFX8552&from=timeline
[ error ] authorize:366:1597384153.6096
[ error ] Mozilla/5.0 (Linux; Android 10; LIO-AN00 Build/HUAWEILIO-AN00; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/77.0.3865.120 MQQBrowser/6.2 TBS/045318 Mobile Safari/537.36 MMWEBID/8978 MicroMessenger/7.0.17.1720(0x27001138) Process/tools WeChat/arm32 NetType/WIFI Language/zh_CN ABI/arm64
---------------------------------------------------------------
[ 2020-08-14T13:49:15+08:00 ] 218.75.60.198 GET /ident-Share-callback.html?goto=https%3A%2F%2Fwww.dichanw.com%2Fwap%2Fhousedetail%2FH614064154%2Fshare&handler=RELATION&partner=WOFX8552&debug=&code=001uKY0w3RLHLU26os3w3whV6X0uKY0m&state=Lpz8C4MW4K5i
[ error ] callback:408:1597384154.4898
[ error ] redirect:577:1597384155.1489
---------------------------------------------------------------
[ 2020-08-14T13:49:16+08:00 ] 122.238.188.128 GET /ident-Share-callback.html?goto=https%3A%2F%2Fwww.dichanw.com%2Fwap%2Fnews%2Fdetail%3F_id%3D137&handler=RELATION&partner=NHVB7537&debug=&code=071fKjnl2IyLt54Yudnl2XwHYy2fKjnI&state=IhT896dLYNli
[ error ] callback:408:1597384155.6382
[ error ] redirect:577:1597384156.2655
---------------------------------------------------------------
[ 2020-08-14T13:49:38+08:00 ] 223.104.212.114 GET /ident-share-page.html?page=https%3A//www.dichanw.com/wap/housedetail/H92791003/share&handler=RELATION&method=userInfo&partner=UETR6909
[ error ] authorize:366:1597384178.6169
[ error ] Mozilla/5.0 (iPhone; CPU iPhone OS 13_5_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/7.0.14(0x17000e2e) NetType/4G Language/zh_CN
---------------------------------------------------------------
[ 2020-08-14T13:49:42+08:00 ] 223.104.212.114 GET /ident-Share-callback.html?goto=https%3A%2F%2Fwww.dichanw.com%2Fwap%2Fhousedetail%2FH92791003%2Fshare&handler=RELATION&partner=UETR6909&debug=&code=021iSw1w3hV9LU2gXH3w3SIIGz1iSw1N&state=5QrLstDaHrLH
[ error ] callback:408:1597384181.8158
[ error ] redirect:577:1597384182.4635

上述日志中多数ip的日志是成对出现的,authorize和callback的时间戳也很接近。比如最前面的两条日志,都是125.123.211.84的请求。

再来观察第三条ip为122.238.188.128的authorize日志,在倒数第三条才找到对应的callback日志,两个时间戳差为1597384155.6382 - 1597384147.3108 = 8.3秒,用户等待了超过8秒的白屏才开始有所反应,这是比较典型的回调很慢的例子。

能够找到这种时间差好几秒的日志例子其实不多的,多数是只有authorize而没有callback日志的例子,有两种可能:1、用户没有耐心,看到一直白屏直接关掉了;2、用户一直等待,微信根本没有callback回来。

因为跳转回调主要在微信端处理,所以作为开发者,能做的好像很有限,不知道如何解决这个问题。你们有遇到类似的问题吗?

最后一次编辑于  2020-08-14
回答关注问题邀请回答
收藏

5 个回答

  • 姜
    2022-09-06

    同样情况, 日志显示几百毫秒, 安卓就是会白屏一会儿( 7-8秒 )才跳回来, 苹果就不到一秒

    2022-09-06
    有用
    回复 2
  • 曹
    2021-11-22

    有结果吗,一样慢

    2021-11-22
    有用
    回复
  • 任小春
    任小春
    2021-01-19

    又是一个没结果的问题...

    2021-01-19
    有用
    回复
  • 疯狂的小辣椒
    疯狂的小辣椒
    2020-08-18

    你好,请提供下具体复现链接

    2020-08-18
    有用
    回复 2
  • 禾朱🌏
    禾朱🌏
    2020-08-14
    网上搜索“微信授权登录 白屏”可以发现发生这种现象的例子还是蛮多的,不过多数没有答案。
    白屏的原因还是比较容易理解的:浏览器页面已经跳转到微信的https://open.weixin.qq.com/connect/oauth2/authorize,而该页面正常情况下是没有任何输出的,它的正常功能是根据微信用户和公众号的关系判断是否需要用户授权,如果需要弹出请求框让用户同意,最后计算出本次调用的code,再让浏览器跳转回到用户的回调地址(这个时候携带了code参数)。如果微信后台在某些特殊情况下(比如卡顿)没有让浏览器跳转回到用户的回调页面,那么页面就一直空白了。
    
    2020-08-14
    有用
    回复
登录 后发表内容
问题标签