腾讯云应用生成 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号