手把手教你给网站增加微信扫码登录功能

在网站开发中,我们经常会遇到需要给网站增加微信扫码登录的功能,一般来说有两种方式可以实现,一种是使用微信开放平台,另一种是使用微信认证服务号的参数二维码,网上以第一种居多,我们今天来说下第二种方式。 首先准备一个【已认证】的微信服务号 将公众号添加至【柠聚开发者平台】中,如图1:

image

然后将生成的回调URL添加至微信公众平台中,如图:

image

这样基础配置就完了,下面我们开始码代码。 首先获取带参数二维码:接口文档见:获取带参数二维码-柠聚开发者平台-柠聚开发者平台 (21ds.cn)

function getWxQrcode($scene)
{
    $apiUrl = 'https://21ds.cn/mpWeixinApi/getQrcode';
    $postData['scene_str'] = $scene;
    $postData['action_name'] = 'QR_STR_SCENE';
    $postData['expire_seconds'] = 120;
    $postData['dev_key'] = 'DEV-xxxxxx';
    $postData['mw_id'] = 'MW4xxxxxx';
    $postData['sign'] = devSignGeneral($postData, 'Wxaxwsxssss');
    $http = new \Yurun\Util\HttpRequest;
    $response = $http->post($apiUrl, $postData);
    $result = json_decode($response->body(), true);
    if ($result['code'] == 200) {
        return $result['data'];
    }
    return [];
}

定义完请求函数后,我们调用这个函数获取到二维码返回给前端:(注:我们在定义参数二维码的scene值时,增加了demo::,这个主要是用来获取到scene事件时寻找请求api接口的,从而可以实现一个微信服务号对接多个网站的二维码登录)

public function get_wechat_login_qrcode(){
    $uuid = createId();
    (new RedisCache)->getSetQrcodeLoginUUID($uuid, 1, 120);
    $data = getWxQrcode('demo::' . $uuid);
    if (empty($data)) {
      return json(['code' => -1, 'msg' => '二维码获取失败']);
    }
    $return['qrcode'] = $data['qrcode_pic'];
    $return['url'] = $data['url'];
    $return['token'] = $uuid;
    return json(['code' => 200, 'msg' => 'success', 'data' => $return]);
  }

其中,getSetQrcodeLoginUUID这个函数用来存储登录状态,函数代码为:

public function getSetQrcodeLoginUUID($key, $data = '', $expireTime = 300)
    {
        $tokenInfo = '';
        if (!empty($data) && !empty($key)) {
            self::$redis->set('demo:loginUUID:' . $key, $data, $expireTime);
        } else {
            $cacheTTL = self::$redis->ttl('demo:loginUUID:' . $key);
            if ($cacheTTL === -1 || $cacheTTL > $expireTime) {
                self::$redis->del('demo:loginUUID:' . $key);
            }
            if (self::$redis->exists('demo:loginUUID:' . $key) > 0) {
                $data_s = self::$redis->get('libs:loginUUID:' . $key);
                $tokenInfo = $data_s;
            }
            return $tokenInfo;
        }
    }

访问get_wechat_login_qrcode函数后,可以获取的“qrcode”及”url”参数,其中qrcode是二维码图片,url是一个链接,可以用来生成二维码图片,根据自己的需要自主选择使用哪个参数即可。 获取到二维码图片后,使用微信扫描二维码后,用户需要关注微信服务号(如未关注过)或者直接进入了微信服务号窗口,此时,将触发微信的事件通知,通知会寻找在图1的“事件通知API”定义的demo的通知接口,如在事件通知api中,我们定义了一个:demo:: 接口,柠聚开发者平台将post事件通知到此接口,定义的接口文档参见:接收事件通知-柠聚开发者平台-柠聚开发者平台 (21ds.cn) 然后我们根据事件的key值便可进行业务处理了,以下为demo代码:

// 使用带参数二维码扫码登录接口
  public function wechat_login()
  {
    if (request()->isPost()) {
      $rule = [
        'event_key'  => 'require',
        'open_id'  => 'require',
      ];
      $data = [
        'event_key'  => input('param.event_key', '', 'trim'),
        'open_id'  => input('param.open_id', '', 'trim'),
      ];
      $validate = Validate::rule($rule);
      $result   = $validate->check($data);
      if (!$result) {
        return Result::Success(['content' => $validate->getError()], 'fail');
      }
      $event_key = $data['event_key'];
      $open_id = $data['open_id'];
      $event_key = str_replace('demo::', '', $event_key);
      if (empty($open_id)) {
        return Result::Success(['content' => '必要参数为空'], 'fail');
      }
      $hasUser = demoUserModel::where('wechat_open_id', $open_id)->find();
      if (empty($hasUser)) {
        (new RedisCache)->getSetQrcodeLoginUUID($event_key, -3, 120);
         return Result::Success(['content' => '您还未绑定平台账号,请【使用账号密码】登录平台并绑定后再试'], 'fail');
      }
      if ($hasUser['status'] != 1) {
        return Result::Success(['content' => '用户状态异常或被封禁,请联系上级管理进行处理。'], 'fail');
      }
      //更新会员状态
      $param = [
        'login_times' => $hasUser['login_times'] + 1,
        'login_ip' => $ip,
        'login_time' => $time,
      ];
      demoUserModel::where('id', $hasUser['id'])->update($param);
      $payload['uid']       = $hasUser['id'];
      $payload['password']       = $hasUser['password'];
      $payload['loginTime'] = $time;
      $token = think_encrypt(json_encode($payload));
      $tokenArr['userToken'] = $token;
      //用户登录有效期
      $loginExpireTime = 86400;
      $loginRefreshExpireTime = 86400;
      // 存储用户token
      $this->redis->set('token-' . $hasUser['id'], $token, $loginExpireTime);
      $tokenArr['Expire'] = $loginExpireTime * 1000;
      $tokenArr['isSuper'] = $hasUser['is_admin'];
      $tokenArr['username'] = $hasUser['username'];
      $tokenArr['avatar'] = $hasUser['avatar'];
      (new RedisCache)->getSetQrcodeLoginUUID($event_key, json_encode($tokenArr, true));
      return Result::Success(['content' => $hasUser['username'] . ' 通过扫码登录【XXXXX网站】成功'], '登录成功,页面将自动跳转……');
    }
    return Result::Success(['content' => '请求不正常'], 'fail');
  }

至此,我们完成了微信扫码登录的整套流程。

 
posted @ 2023-11-02 17:04  千龙18  阅读(376)  评论(0)    收藏  举报