9 April 2021 - 字数统计：3260 - 阅读大约需要11分钟 - Hits: Loading...

# 自制微信二维码登录API

by mayx

这是一篇创建于 天前的文章，其中的信息可能已经有所发展或是发生改变。

AI摘要

这篇文章主要介绍了制作微信二维码登录API的过程，作者希望通过模块化的方式简化服务，允许开发者通过扫描二维码获取用户的唯一标识OpenID。API涉及设置和获取OpenID的功能，通过POST请求创建二维码，以及验证用户的扫码事件以获取或验证OpenID。开发者需先存储OpenID，使用随机的key命名，且建议使用UUID。作者强调代码可能存在安全漏洞，期待安全专家的意见进行改进。此外，API还可以用于网站扫码绑定登录和推送消息。

- 起因
- 代码
- 使用文档
  - 接口调用方法
  - 说明
  - 使用示例
  - 注意事项

二维码登录看来也不是什么复杂的东西嘛

#
起因

前段时间我用了一位大佬的认证公众号做了一个微信推送的API，并且希望把它做成像WxPusher那样的平台。但是吧……我想了想，现在微服务不是比较火嘛，WxPusher那种的实在是太臃肿了，而且还是用Java写的，那就更加垃圾了，所以我决定把功能模块化，让每一个功能都可以单独运行，互不影响。

而今天我要做的就是允许A用户（开发者）使用微信扫描二维码的方式去获取B用户（客户）的用户ID。当然这种功能的话肯定还是用PHP完成的啦，所以代码如下：

#
代码

    <?php
    $appid='公众号APPID';
    $secret='公众号Secret';
    $token='和配置的Token配置一致即可';

    ini_set('session.gc_maxlifetime', 7200);
    session_id('Storagepush');
    session_start();
    if(!json_decode(file_get_contents('https://api.weixin.qq.com/cgi-bin/get_api_domain_ip?access_token='.$_SESSION['access_token']),true)['ip_list']){
    $_SESSION['access_token']=json_decode(file_get_contents('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$secret),true)['access_token'];
    }
    if(isset($_GET["action"])&&isset($_GET["key"])){
    $_GET["key"]=addslashes($_GET["key"]);
    if(strlen($_GET["key"])<6||strlen($_GET["key"])>32){
        die("Bad Key");
    }

    if($_GET["action"] == "set"){
        echo file_get_contents('https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token='.$_SESSION['access_token'], false, stream_context_create(array('http' => array('method'=>'POST','header'=>"Content-Type: application/json;charset=utf-8",'content'=>'{"expire_seconds": 3600, "action_name": "QR_STR_SCENE", "action_info": {"scene": {"scene_str": "auth'.$_GET["key"].'"}}}'))));
    }
    if ($_GET["action"] == "get") {
        if(isset($_SESSION['wxboxauth'.$_GET["key"]])){
            echo $_SESSION['wxboxauth'.$_GET["key"]];
        }else{
            echo "Empty";
        }
    }

    }else{

    $timestamp=$_GET["timestamp"];
    $nonce=$_GET["nonce"];
    $tmpArr=array($token, $timestamp, $nonce);
    sort($tmpArr, SORT_STRING);
    if( sha1(implode($tmpArr)) == $_GET["signature"] ){
    if($_GET["echostr"]){
    echo $_GET["echostr"];
    }else{
    //  加载XML内容
    $content = file_get_contents("php://input");
    $p = xml_parser_create();
    xml_parse_into_struct($p, $content, $vals, $index);
    xml_parser_free($p);
    if(($vals[$index['EVENT'][0]]['value'] == "subscribe" || $vals[$index['EVENT'][0]]['value'] == "SCAN") && isset($vals[$index['EVENTKEY'][0]]['value'])){
        if($vals[$index['EVENT'][0]]['value'] == "subscribe"){
            $vals[$index['EVENTKEY'][0]]['value'] = substr($vals[$index['EVENTKEY'][0]]['value'],8);
        }
        $_SESSION['wxbox'.$vals[$index['EVENTKEY'][0]]['value']] = $vals[$index['FROMUSERNAME'][0]]['value'];
        echo '<xml>
      <ToUserName><![CDATA['.$vals[$index['FROMUSERNAME'][0]]['value'].']]></ToUserName>
      <FromUserName><![CDATA['.$vals[$index['TOUSERNAME'][0]]['value'].']]></FromUserName>
      <CreateTime>'.time().'</CreateTime>
      <MsgType><![CDATA[text]]></MsgType>
      <Content><![CDATA[成功请求登录！]]></Content>
    </xml>';
    }else{
    echo "success";
    }
    }
    }else{
        echo "Fail";
    }
    }

#
使用文档

##
接口调用方法

参数 | 是否必填 | 请求方法 | 内容
--- | --- | --- | ---
action | 是 | GET | set/get
key | 是 | GET | 6-32字节长度的随机字符串

##
说明

开发者需要先使用set方法设置一个存储用户OPENID的盒子，使用key来命名，为了避免重复，这里推荐使用32位的UUID作为名称，请求完成之后会获得一个有效时长为1小时的二维码的ticket和二维码的地址，可以如果希望自己生成二维码，可以使用返回的URL作为二维码的内容，或者也可以调用微信的Ticket转二维码接口，在`https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=`后面加上获得的Ticket就可以直接获得二维码的图片。

获取OPENID需要使用get方法去获得命名为key的盒子，如果用户已经扫描了二维码，那么调用此接口会直接返回扫描者的OPENID，如果没有扫描或者用户扫描后超过了2个小时，就会返回Empty，以表示盒子为空。

##
使用示例

像我之前写的微信推送中不是就需要这个用户的OPENID嘛，假如一个网站想要主动给某些用户推送消息，就可以先调用这个接口获得用户的OPENID，然后存起来，有必要时可以直接使用微信推送来给用户推送信息。另外这个OPENID是唯一的，所以假如想做网站二维码扫描绑定登录同样也可以使用这个接口。具体实现就非常简单了，所以示例代码我就不写了。

##
注意事项

像这个代码依然不防滥用，并且我也没有检验过安全性，是有很大可能有漏洞的。所以有懂安全的大佬也可以指点一下，来完善这个项目。

tags: 微信 - 登录 - 验证 - PHP 查看原始文件

#### 推荐文章

Loading...

上一篇：Mayx的产品测评（三）
下一篇：Mayx的运维笔记 - 隐藏自己
想问这篇文章
召唤伊斯特瓦尔