基于微信公众号开发生成带参数的二维码及三方登录,开发思路,流程

发表于 2021-02-18  1.19k 次阅读


UXW18GEKPSVBFRYJ4RBOTWIPXG07FSMK_0.jpg

这个功能需要有个一个已认证的公众号,厉害的是!在下没有~

当然~我们可以通过微信测试号来完成这些开发,测试账号拥有公众号所有的接口,不管是订阅号还是服务号,只是不能群发信息。用来开发带参数的二维码也是绰绰有余~

一、开发准备

打开注册网址:https://mp.weixin.qq.com/debug/cgi-bin/sandboxinfo?action=showinfo&t=sandbox/login

点击登录,使用微信扫一扫即可进入你的微信公众测试平台

QQ图片20180810150842.png

如图,你会看到测试平台的微信号,appID,appsecret,其中appID和appsecret这两个对于公众号来说十分重要,请不要随便给他人看或者使用~

二、接入

接下来我们启用公众号服务器配置

QQ图片20180810151647.png

此动作对应了正常公众号中开发->基本配置操作

QQ图片20180810151820.png

我们用测试平台开发的话,默认是明文模式,所以消息加解密密钥是没有的,并且下方所有的信息都是明文模式,如需要加密,可阅读微信接入说明和下载微信加密解密代码。微信接入链接

这里的URL对应的是微信推送接入地址,第一次接入的话,我们需要代码认证一下才能接入完成,之后所有的微信公众号的操作,微信方都会推送信息到这个链接中,我们可以根据推送的信息来处理自己的逻辑,和发送信息。(微信推送的信息是XML格式

如第一次接入,微信会传递signature(接入签名),timestamp(时间戳),nonce(随机数),echostr(随机字符串),当我们接收到这4个参数后,需要时间戳和随机数成数组,排序,数字转字符串,sha1加密操作,与signature比较,一致的话代表是微信端发来的信息,并输出nonce,代表接入完成。

$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$echostr = $_GET["echostr"];

$tmpArr = array($timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );

if( $signature == $tmpStr ){
    echo $echostr;
}else{
    echo "false";
}

此操作仅仅在第一次接入执行即可,后续就不会用到它了,可以回家喝茶了

QQ图片20180810172915.png

接入完成后,就可以开始我们的带参数二维码的开发了。

三、基础方法

class WeChatUnit
{
    public function curlPostFun($url, $data)
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        // post数据
        curl_setopt($ch, CURLOPT_POST, 1);
        // post的变量
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }
}

四、获取access_token

access_token是公众号的全局唯一接口调用凭据,公众号调用各接口时都需使用access_token。开发者需要进行妥善保存。access_token的存储至少要保留512个字符空间。access_token的有效期目前为2个小时,需定时刷新,重复获取将导致上次获取的access_token失效。

    private $AppId = "";
    private $Secret = "";

    public function getAccessToken()
    {
        //res是数据库记录的accessToken
        $res = [];
        //数据库中获取
        if ($res['accessToken'] !== null && $res['deadlineTime'] !== null && time() - $res['deadline_time'] > 7200 )
        {
            return ["success" => true, "data" => $res['accessToken'], "message" => ""];
        }

        //微信请求
        $get_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->AppId}&secret={$this->Secret}";
        $res = $this->curlPostFun($get_token_url, []);
        $res = json_decode($res, true);
        if (!empty($res['errcode']))
        {
            return ["success" => false, "data" => null, "message" => $res['errmsg']];
        }

        //更新数据库accessToken

        return ["success" => true, "data" => $res['access_token'], "message" => ""];
    }

在开发中,不管什么接口都需要access_token,注意这个获取access_token的接口是有每日次数限制的,并且还有有效时间(7200秒),在使用时需要记录下来。

五、生成带参数的二维码

生成带参数的二维码大体步骤是:获取accessToken,通过accessToken获取二维码ticket,再通过二维码ticket得到二维码图片。

    public function getImageUrlAndId()
    {
        $tokenRes = $this->getAccessToken();
        if (!$tokenRes["success"])
        {
            return ["success" => false, "data" => null, "message" => $tokenRes['message']];
        }
        //获取
        $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=" . $tokenRes["data"];

        $postData = [
            "expire_seconds" => 300,//有效时间(秒)
            "action_name" => "QR_STR_SCENE",//scene_str标识类型,QR_STR_SCENE临时的字符串
            "action_info" => ["scene" => ["scene_str" => "quickLogin"]] //scene_str是扫描后回传给服务器地址中的
        ];
        $postData = json_encode($postData);
        $res = json_decode($this->curlPostFun($url ,$postData), true);
        if (!empty($res['errcode']))
        {
            return ["success" => false, "data" => null, "message" => $res['errmsg']];
        }
        $ticketId = 记录账号标识($res['ticket']);
        if ($ticketId == 0)
        {
            return ["success" => false, "data" => null, "message" => "添加失败"];
        }

        //这个链接是二维码的连接
        $ticket_url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" . $res['ticket'];
        return ["success" => true, "data" => ["url" => $ticket_url, "id" => $ticketId], "message" => ""];
    }

为了做扫码登录,需要记录当前二维码的ticket值,存到数据库中

前台得到这个二维码的链接显示出来就行,并轮询使用得到的id请求数据库是否被扫描(懒,不想写了,大概就是查看是否扫描了,扫描事件在下面)。

六、接收微信扫描事件

还记得我们配的那个接入url吗?不记得的话看下第二步就行~

微信扫描二维码后,微信服务端会推送事件给接入url。

已关注公众号推送信息

<xml><ToUserName><![CDATA[gh_xxxxxxxxx]]></ToUserName>
<FromUserName><![CDATA[odK-ct46AaD9ZL-YXHSJa231]]></FromUserName>
<CreateTime>1534757213</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[SCAN]]></Event>
<EventKey><![CDATA[quickLogin]]></EventKey>
<Ticket><![CDATA[gQGG7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyYTJ2NUJZUUxhc1QxcC1EWSDxsdXCS]]></Ticket>
</xml>

未关注公众号推送信息

<xml><ToUserName><![CDATA[gh_xxxxxxxxx]]></ToUserName>
<FromUserName><![CDATA[odK-ct46AaD9ZL-YXHSJa231-Q0]]></FromUserName>
<CreateTime>1534759544</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[qrscene_quickLogin]]></EventKey>
<Ticket><![CDATA[gQGG7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyYTJ2NUJZUUxhc1QxcC1EWSDxsdXCS]]></Ticket>

ToUserName:发起人(公众号的微信号)

FromUserName:用户的openId

CreateTime:请求时间戳

MsgType:信息类型(event:事件)

Event:事件类型

EventKey:事件标识

Ticket:扫描事件带的ticket,与上面的ticket一致

接收url接收并解析:

$xmldata=file_get_contents("php://input");
$postObj = simplexml_load_string($xmldata, 'SimpleXMLElement', LIBXML_NOCDATA);

确认是扫码关注登录信息

$msgType = $postObj->MsgType;
if ($msgType == "event")
{
    $eventKey = $postObj->EventKey;
    $event = $postObj->Event;
    $openId = $postObj->FromUserName;
    if (($event == "SCAN" || $event == "subscribe") && ($eventKey == "quickLogin" || $eventKey = "qrscene_quickLogin"))
    {
        //实现逻辑
        $ticket = $postObj->Ticket; //ticket是在生产二维码是的ticket
        //根据ticket,$openId处理登录信息
    }
}

前台轮询查看此二维码是否扫码,扫描登陆

微信的基于公众号第三方登录大体就完成了

关于为什么使用带参数的二维码来做微信的第三方登录:

在开发公众号网站的时候,通常会用到openID来作为用户的识别,用户扫描带参数的二维码后微信推过来的数据中也带有openID,这样比较方便数据互通(虽然unionID也是这个功能)。

在用户扫描二维码时,微信端会判断用户是否关注公众号,关注则进入公众号,未关注则让他关注,加强对公众号的推广。何乐而不为呢~

本站文章基于国际协议BY-NA-SA 4.0协议共享;
如未特殊说明,本站文章皆为原创文章,请规范转载。

0

一盏灯 一座城 找一人 一路的颠沛流离