騰訊雲應用生成 UserSig


騰訊雲相關的即時通訊IM,實時音視頻等相關都需要生成UserSig;

騰訊雲已經非常明確的告訴我們如何生成UserSig

對應文檔地址:https://cloud.tencent.com/document/product/269/32688

對應PHP版本GIT下載地址:https://github.com/tencentyun/tls-sig-api-v2-php/blob/master/src/TLSSigAPIv2.php

寫這個博客是為了給下一篇博客做引用。各位看官大佬勿怪。

直接復制粘貼內容過來,哈哈:

<?php

namespace Tencent;

if (version_compare(PHP_VERSION, '5.1.2') < 0) {
    trigger_error('need php 5.1.2 or newer', E_USER_ERROR);
}

class TLSSigAPIv2 {

    private $key = false;
    private $sdkappid = 0;

    public function __construct($sdkappid, $key) {
        $this->sdkappid = $sdkappid;
        $this->key = $key;
    }

    /**
     * 用於 url 的 base64 encode
     * '+' => '*', '/' => '-', '=' => '_'
     * @param string $string 需要編碼的數據
     * @return string 編碼后的base64串,失敗返回false
     * @throws \Exception
     */
    private function base64_url_encode($string) {
        static $replace = Array('+' => '*', '/' => '-', '=' => '_');
        $base64 = base64_encode($string);
        if ($base64 === false) {
            throw new \Exception('base64_encode error');
        }
        return str_replace(array_keys($replace), array_values($replace), $base64);
    }

    /**
     * 用於 url 的 base64 decode
     * '+' => '*', '/' => '-', '=' => '_'
     * @param string $base64 需要解碼的base64串
     * @return string 解碼后的數據,失敗返回false
     * @throws \Exception
     */
    private function base64_url_decode($base64) {
        static $replace = Array('+' => '*', '/' => '-', '=' => '_');
        $string = str_replace(array_values($replace), array_keys($replace), $base64);
        $result = base64_decode($string);
        if ($result == false) {
            throw new \Exception('base64_url_decode error');
        }
        return $result;
    }

    /**
     * 使用 hmac sha256 生成 sig 字段內容,經過 base64 編碼
     * @param $identifier 用戶名,utf-8 編碼
     * @param $curr_time 當前生成 sig 的 unix 時間戳
     * @param $expire 有效期,單位秒
     * @param $base64_userbuf base64 編碼后的 userbuf
     * @param $userbuf_enabled 是否開啟 userbuf
     * @return string base64 后的 sig
     */
    private function hmacsha256($identifier, $curr_time, $expire, $base64_userbuf, $userbuf_enabled) {
        $content_to_be_signed = "TLS.identifier:" . $identifier . "\n"
            . "TLS.sdkappid:" . $this->sdkappid . "\n"
            . "TLS.time:" . $curr_time . "\n"
            . "TLS.expire:" . $expire . "\n";
        if (true == $userbuf_enabled) {
            $content_to_be_signed .= "TLS.userbuf:" . $base64_userbuf . "\n";
        }
        return base64_encode(hash_hmac( 'sha256', $content_to_be_signed, $this->key, true));
    }

    /**
     * 生成簽名。
     *
     * @param $identifier 用戶賬號
     * @param int $expire 過期時間,單位秒,默認 180 天
     * @param $userbuf base64 編碼后的 userbuf
     * @param $userbuf_enabled 是否開啟 userbuf
     * @return string 簽名字符串
     * @throws \Exception
     */
    private function __genSig($identifier, $expire, $userbuf, $userbuf_enabled) {
        $curr_time = time();
        $sig_array = Array(
            'TLS.ver' => '2.0',
            'TLS.identifier' => strval($identifier),
            'TLS.sdkappid' => intval($this->sdkappid),
            'TLS.expire' => intval($expire),
            'TLS.time' => intval($curr_time)
        );

        $base64_userbuf = '';
        if (true == $userbuf_enabled) {
            $base64_userbuf = base64_encode($userbuf);
            $sig_array['TLS.userbuf'] = strval($base64_userbuf);
        }

        $sig_array['TLS.sig'] = $this->hmacsha256($identifier, $curr_time, $expire, $base64_userbuf, $userbuf_enabled);
        if ($sig_array['TLS.sig'] === false) {
            throw new \Exception('base64_encode error');
        }
        $json_str_sig = json_encode($sig_array);
        if ($json_str_sig === false) {
            throw new \Exception('json_encode error');
        }
        $compressed = gzcompress($json_str_sig);
        if ($compressed === false) {
            throw new \Exception('gzcompress error');
        }
        return $this->base64_url_encode($compressed);
    }


    /**
     * 生成簽名
     *
     * @param $identifier 用戶賬號
     * @param int $expire 過期時間,單位秒,默認 180 天
     * @return string 簽名字符串
     * @throws \Exception
     */
    public function genSig($identifier, $expire=86400*180) {
        return $this->__genSig($identifier, $expire, '', false);
    }

    /**
     * 帶 userbuf 生成簽名。
     * @param $identifier 用戶賬號
     * @param int $expire 過期時間,單位秒,默認 180 天
     * @param string $userbuf 用戶數據
     * @return string 簽名字符串
     * @throws \Exception
     */
    public function genSigWithUserBuf($identifier, $expire, $userbuf) {
        return $this->__genSig($identifier, $expire, $userbuf, true);
    }


    /**
     * 驗證簽名。
     *
     * @param string $sig 簽名內容
     * @param string $identifier 需要驗證用戶名,utf-8 編碼
     * @param int $init_time 返回的生成時間,unix 時間戳
     * @param int $expire_time 返回的有效期,單位秒
     * @param string $userbuf 返回的用戶數據
     * @param string $error_msg 失敗時的錯誤信息
     * @return boolean 驗證是否成功
     * @throws \Exception
     */
    private function __verifySig($sig, $identifier, &$init_time, &$expire_time, &$userbuf, &$error_msg) {
        try {
            $error_msg = '';
            $compressed_sig = $this->base64_url_decode($sig);
            $pre_level = error_reporting(E_ERROR);
            $uncompressed_sig = gzuncompress($compressed_sig);
            error_reporting($pre_level);
            if ($uncompressed_sig === false) {
                throw new \Exception('gzuncompress error');
            }
            $sig_doc = json_decode($uncompressed_sig);
            if ($sig_doc == false) {
                throw new \Exception('json_decode error');
            }
            $sig_doc = (array)$sig_doc;
            if ($sig_doc['TLS.identifier'] !== $identifier) {
                throw new \Exception("identifier dosen't match");
            }
            if ($sig_doc['TLS.sdkappid'] != $this->sdkappid) {
                throw new \Exception("sdkappid dosen't match");
            }
            $sig = $sig_doc['TLS.sig'];
            if ($sig == false) {
                throw new \Exception('sig field is missing');
            }

            $init_time = $sig_doc['TLS.time'];
            $expire_time = $sig_doc['TLS.expire'];

            $curr_time = time();
            if ($curr_time > $init_time+$expire_time) {
                throw new \Exception('sig expired');
            }

            $userbuf_enabled = false;
            $base64_userbuf = '';
            if (isset($sig_doc['TLS.userbuf'])) {
                $base64_userbuf = $sig_doc['TLS.userbuf'];
                $userbuf = base64_decode($base64_userbuf);
                $userbuf_enabled = true;
            }
            $sigCalculated = $this->hmacsha256($identifier, $init_time, $expire_time, $base64_userbuf, $userbuf_enabled);

            if ($sig != $sigCalculated) {
                throw new \Exception('verify failed');
            }

            return true;
        } catch (\Exception $ex) {
            $error_msg = $ex->getMessage();
            return false;
        }
    }


    /**
     * 帶 userbuf 驗證簽名。
     *
     * @param string $sig 簽名內容
     * @param string $identifier 需要驗證用戶名,utf-8 編碼
     * @param int $init_time 返回的生成時間,unix 時間戳
     * @param int $expire_time 返回的有效期,單位秒
     * @param string $error_msg 失敗時的錯誤信息
     * @return boolean 驗證是否成功
     * @throws \Exception
     */
    public function verifySig($sig, $identifier, &$init_time, &$expire_time, &$error_msg) {
        $userbuf = '';
        return $this->__verifySig($sig, $identifier, $init_time, $expire_time, $userbuf, $error_msg);
    }

    /**
     * 驗證簽名
     * @param string $sig 簽名內容
     * @param string $identifier 需要驗證用戶名,utf-8 編碼
     * @param int $init_time 返回的生成時間,unix 時間戳
     * @param int $expire_time 返回的有效期,單位秒
     * @param string $userbuf 返回的用戶數據
     * @param string $error_msg 失敗時的錯誤信息
     * @return boolean 驗證是否成功
     * @throws \Exception
     */
    public function verifySigWithUserBuf($sig, $identifier, &$init_time, &$expire_time, &$userbuf, &$error_msg) {
        return $this->__verifySig($sig, $identifier, $init_time, $expire_time, $userbuf, $error_msg);
    }
}

然后是對應調用直接使用:

    $api = new TLSSigAPIv2($sdkappid,$key);
    $userSig = $api->genSig($identifier); 

即可,完成

此篇為下篇 即時通訊IM 的一個分支文章

感謝各位大佬閱覽

 

2020年08月10號


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM