通过微信小程序实现扫码登录


一直想做微信扫码登录,但是一个小博客网站,本来就不是盈利性质的,还要每年再支付开放平台的认证费用,实在没什么开发动力。最近使用腾讯文档,发现腾讯文档的扫码登录用的小程序,所以探索一下用微信小程序实现扫码登录。

----更新中,您当前看到的可能不是最新内容

一、首先描述一下使用场景

用户在后台可以通过扫一个二维码来绑定微信,之后即可在登录的时候选择微信扫码登录。

二、实现基础

1. 表设计

用户表不说,需要一个表存储用户、微信和小程序的对应关系,表设计如下: id,user_id,appid,openid,created_at,updated_at

2. 二维码生成

微信小程序的扫普通二维码打开小程序需要企业认证,不过对于个人认证小程序提供了生成小程序acode的后端api,具体的后端api文档可以看这里。 生成二维码的时候可以设置scene参数来携带需要的参数,使用page参数来设置扫码后打开的小程序页面。

3. 小程序接口

3.1 绑定

post:/api/users/ianzhi/wechat token: 二维码携带的识别令牌 api_token: api访问令牌

3.2 登录

post:/api/login/wechat token: 二维码携带的识别令牌 api_token:api访问令牌

三、具体实现

1. 生成二维码


    /**
     * 获取不受限制的小程序二维码
     *
     * @param $page string 页面路径
     * @param $scene string 携带参数
     * @param $width int 宽度
     * @param $color array 颜色
     * @param $isHyaline boolean 是否透明底色
     * @return string
     *
     * @throws Exception
     */
    public function unlimitedAcode(string $scene, string $page='', int $width=50, array $color=[], bool $isHyaline=false)
    {
        $url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit';
        $query = [
          'access_token' => $this->accessToken()
        ];

        $data = [
            'scene' => $scene,
            'width' => $width,
            'auto_color' => $color ? false : true,
            'is_hyaline' => $isHyaline
        ];
        if ($page) {
            $data['page'] = $page;
        }
        if (!$data['auto_color']) {
            $data['line_color'] = [
                'r' => $color[0],
                'g' => $color[1],
                'b' => $color[2]
            ];
        }

        $client = new Client([
            'query' => $query,
            'body' => json_encode($data)
        ]);
        $res = $client->post($url);
        return $res->getBody()->getContents();
    }

2. 生成具体包含业务逻辑的小程序码

/**
     * 用于用户绑定小程序的二维码
     * get: /users/ianzhi/wechat?mp=aaa
     * @param Request $request
     * @return ResponseFactory|Response
     * @throws Exception
     */
    public function wechatQrcode(Request $request)
    {
        $mp = $request->mp;
        $token = md5($mp . $request->user()->name . time() . uniqid());
        cache([$token => ['mp' => $mp]], Carbon::now()->addMinutes(5));
        return response($mp->unlimitedQrcode($token, 'pages/weblogin/weblogin'))
            ->withHeaders([ 'content-type'=> 'image/png' ]);
    }

3. 后台绑定页面

这个不再贴代码了,有二维码生成方法,基本没什么难度。

4. 小程序扫码后确认绑定

这个主要是使用scene接收一下二维码的scene参数,之后调用微信登录api,并向后台发送code和scene。

---- 持续更新中