百度小程序一键取号 · 解密取号

5 篇文章 0 订阅
1 篇文章 0 订阅

封装成了个类,参数有注解,请自行更正没有的类,没有的方法

httpRequest();方法类中有,不需要 json_encode

代码如下:

<?php

/**
 * @author lianyu001 <1411479499@qq.com>
 * start_time   2022-06-28
 * up_time      2022-06-28
 * end_time     2022-06-28
 */
if (!defined('WY_ROOT'))
    exit;
require_once dirname(WY_ROOT) . '/ApiV1/function_apiv1.php';

Class baidu_applet_config {

    private $appid = 'xxx'; //账号名
    private $secred = 'xxx'; //账号密码

    /**
     * 百度小程序一键登录获取 手机号
     * @param str $code     由swan.login获取的临时登录凭证,找前端要
     * @param str $sign     待解密数据,encryptedData,找前端小程序要
     * @param str $iv       加密向量,返回的内容中的iv字段,找前端要
     * @return ary[code,msg,data]  200正常,data.mobile 其他抛出msg
     */

    function get_mobile($code, $sign, $iv) {
        $pub = new ALLClass();
        $url = 'https://spapi.baidu.com/oauth/jscode2sessionkey';
        $data = array(
            "code" => $code,
            "client_id" => $this->appid,
            "sk" => $this->secred
        );
        $res = $pub->httpRequest($url, "POST", json_encode($data));
        $res_arr = json_decode($res, TRUE);
        if (isset($res_arr['session_key'])) {
            $phone = $this->decrypt($sign, $iv, $this->appid, $res_arr['session_key']);
            if (!!$phone) {
                $mobile = json_decode($phone, TRUE);
                return ['msg' => 'Success.', 'data' => $mobile, 'code' => 200];
            } else {
                return ['msg' => '解密失败,请检查参数', 'code' => 403];
            }
        } else {
            return ['code' => 500, 'msg' => '百度小程序登录错误,请检查code是否过期'];
        }
    }

    /**
     * 数据解密:低版本使用mcrypt库(PHP < 5.3.0),高版本使用openssl库(PHP >= 5.3.0)。
     * 官方提供解密方法   https://smartprogram.baidu.com/docs/develop/function/login_userdata/
     * @param string $ciphertext    待解密数据,返回的内容中的data字段
     * @param string $iv            加密向量,返回的内容中的iv字段
     * @param string $app_key       创建小程序时生成的app_key
     * @param string $session_key   登录的code换得的
     * @return string | false
     */
    function decrypt($ciphertext, $iv, $app_key, $session_key) {
        $session_key = base64_decode($session_key);
        $iv = base64_decode($iv);
        $ciphertext = base64_decode($ciphertext);
        $plaintext = false;
        if (function_exists("openssl_decrypt")) {
            $plaintext = openssl_decrypt($ciphertext, "AES-192-CBC", $session_key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv);
        } else {
            $td = mcrypt_module_open(MCRYPT_RIJNDAEL_128, null, MCRYPT_MODE_CBC, null);
            mcrypt_generic_init($td, $session_key, $iv);
            $plaintext = mdecrypt_generic($td, $ciphertext);
            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);
        }
        if ($plaintext == false) {
            return false;
        }
        // trim pkcs#7 padding
        $pad = ord(substr($plaintext, -1));
        $pad = ($pad < 1 || $pad > 32) ? 0 : $pad;
        $plaintext = substr($plaintext, 0, strlen($plaintext) - $pad);
        // trim header
        $plaintext = substr($plaintext, 16);
        // get content length
        $unpack = unpack("Nlen/", substr($plaintext, 0, 4));
        // get content
        $content = substr($plaintext, 4, $unpack['len']);
        // get app_key
        $app_key_decode = substr($plaintext, $unpack['len'] + 4);
        return $app_key == $app_key_decode ? $content : false;
    }

    /**
     * CURL请求
     * @param $url 请求url地址
     * @param $method 请求方法 get post
     * @param null $postfields post数据数组
     * @param array $headers 请求header信息
     * @param bool|false $debug  调试开启 默认false
     * @return mixed
     */
    function httpRequest($url, $method = "GET", $postfields = [], $headers = array(), $debug = false) {
        $method = strtoupper($method);
        $ci = curl_init();
        /* Curl settings */
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
        curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 6.2; WOW64; rv:34.0) Gecko/20100101 Firefox/34.0");
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 60); /* 在发起连接前等待的时间,如果设置为0,则无限等待 */
        curl_setopt($ci, CURLOPT_TIMEOUT, 7); /* 设置cURL允许执行的最长秒数 */
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
        switch ($method) {
            case "POST":
                curl_setopt($ci, CURLOPT_POST, true);
                $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
                curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
                break;
            case "GET":
                $params = "";
                foreach ($postfields as $k => $v) {
                    $params .= $k . "=" . urlencode($v) . "&";
                }
                curl_setopt($ci, CURLOPT_POSTFIELDS, $params);
                break;
            default:
                curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
                break;
        }
        $ssl = preg_match('/^https:\/\//i', $url) ? TRUE : FALSE;
        curl_setopt($ci, CURLOPT_URL, $url);
        if ($ssl) {
            curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
            curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
        }
        //curl_setopt($ci, CURLOPT_HEADER, true); /*启用时会将头文件的信息作为数据流输出*/
        curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ci, CURLOPT_MAXREDIRS, 2); /* 指定最多的HTTP重定向的数量,这个选项是和CURLOPT_FOLLOWLOCATION一起使用的 */
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, true);
        /* curl_setopt($ci, CURLOPT_COOKIE, $Cookiestr); * *COOKIE带过去** */
        $response = curl_exec($ci);
        $requestinfo = curl_getinfo($ci);
        $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
        if ($debug) {
            echo "=====post data======\r\n";
            var_dump($postfields);
            echo "=====info===== \r\n";
            print_r($requestinfo);
            echo "=====response=====\r\n";
            print_r($response);
        }
        curl_close($ci);
        return $response;
        //return array($http_code, $response,$requestinfo);
    }

}

调用如下:

<?php 

echo json_encode(get_baidu_mobile());


/**
 * 百度一键登录解密取号
 */
function get_baidu_mobile() {
    $parm = parameters_certification(['code', 'iv', 'sign']);
    if (!$parm) {
        return ['code' => 404, 'msg' => '参数错误.'];
    }
    require_once WY_ROOT . '/config/baidu_applet_config.php';//你的类文件
    $cc = new baidu_applet_config();//new一个女朋友,当然也可以在类中设置静态方法 :: 直接调用就不用new了
    $bb=$cc->get_mobile($parm['code'], $parm['sign'], $parm['iv']);
    if($bb['code'] == 200){
        $_REQUEST['mobile']=$bb['data']['mobile'];
        $_REQUEST['login_type']=5;
        return login('1');
    }
    return $bb;
}
/**
 * 参数验证
 * @param array $field      参数索引数组【'a','b'】
 * @param array $data       需要验证数组,不传拿$_REQUEST
 * @return boolean | array  不存在参数,空参数返回false,否则返回验证数组
 */
function parameters_certification($field = [], $data = []) {
    if (empty($data)) {
        $data = $_REQUEST;
    }
    if (empty($field)) {
        return $data;
    }
    foreach ($field as $val) {
        if (isset($data[$val])) {
            if (is_array($data[$val])) {
                if (empty($data[$val])) {
                    return false;
                } else {
                    continue;
                }
            }
            if (strlen($data[$val]) > 0) {
                continue;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }
    return $data;
}

?>

很简单的,偏偏找不到百度的正确方式

官方demo也给出错误的引导,这文档跳过来,跳过去,很令人懵逼,心态不好还容易暴躁。

步骤:

1.通过前端获取code、iv、sign

2.后端引入类

3.调用类中方法解密输出

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值