Laravel 通过 snsapi_base 静默授权获取用户微信公众号 openid

文章目录

    由于 JSAPI 调用微信支付需要用户的 openid,所以要了解如何获取到 openid。

    还是官方的文档说的清楚

    https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842

    以 snsapi_base 为 scope 发起的网页授权,是用来获取进入页面的用户的 openid 的,并且是静默授权并自动跳转到回调页的。用户感知的就是直接进入了回调页(往往是业务页面)。

    应该是用在登录之后,如果没有绑定 open_id 就应该立即调用授权。

    前端判断是否在微信中,同时判断是否有 openid,如果在微信中,已登录并且没有 openid,则跳转。回调回来时,由于带了 code 参数,所以后台 controller 可以直接获取到 openid。并与当前用户关联。(取消 openid 的唯一索引。因为一个用户可能拥有多个手机号,对应同一个 openid)

    获取 openid 的时机问题

    这取决于业务场景,但是可以肯定的是需要在调用预支付之前,必须获取到 openid。

    Laravel 通过 snsapi_base 静默授权获取用户微信公众号 openid

    实现代码

    $user = Auth::user();
    $code = $request->get('code', '');  # redirect_uri/?code=CODE&state=STATE
    
    // 判断是否在微信中
    $ua = $request->header('User-Agent');
    $is_in_wechat = preg_match('/MicroMessenger/i', $ua);
    
    if ($is_in_wechat && !$user->open_id) {
        // 用户在微信中, 并且没有关联 openid
        if ($code) {
            // 通过 code 获取 open_id
            $client = new Client();
            $url = sprintf("https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code",
                env('WECHAT_APPID'), env('WECHAT_SECRET'), $code);
            try {
                $res = $client->request('GET', $url, ['timeout' => 1.5]);
                $res = $res->getBody();
                $res = json_decode($res);
                $user->open_id = $res->openid;
                $user->save();
            } catch(\Throwable $e) {
                Log::info('Fail to call api');
            }
        } else {
            // 静默授权,跳转获取 code
            $url = sprintf("https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_base#wechat_redirect",
                env('WECHAT_APPID'), urlencode(env('APP_URL') . '/cart'));
            return redirect($url);
        }
    }
    

    返回的 JSON 数据结构

    {
      "access_token": "xxx",
      "expires_in": 7200,
      "refresh_token": "xxx",
      "openid": "xxx",
      "scope": "snsapi_base"
    }
    

    关于作者 🌱

    我是来自山东烟台的一名开发者,有感兴趣的话题,或者软件开发需求,欢迎加微信 zhongwei 聊聊,或者关注我的个人公众号“大象工具”, 查看更多联系方式