对于开发开放接口有很大的帮助,校验码存于header,密钥与内容关联二次加密,同时加上当前时间和随机字符串,安全性很高。 //头部 private static $header = array( 'alg' => 'HS256', //生成signature的算法 'typ' => 'JWT' //类型 ); public $app_id = ''; private $app_secret; private $secretKey = ''; public function __construct($config) { $this->app_id = isset($config['appId']) ? $config['appId'] : ''; $this->app_secret = isset($config['appSecret']) ? $config['appSecret'] : ''; } /** * 获取jwt token * @param array $payload jwt载荷 格式如下非必须 * [ * 'iss'=>'app885656565285656525656312', //该JWT的签发者 * 'iat'=>time(), //每一次请求都进行一次核验,此时间误差再3s范围以内 * 'exp'=>time()+3, //过期时间 * 'nbf'=>time()+10, //10s之后不再接收该token校验 * 'jti'=>md5(uniqid('JWT').time()) //该Token唯一标识 * ] * @return bool|string */ public function getToken() { $now = time(); $payload['iss'] = $this->app_id; $payload['iat'] = $now; $payload['exp'] = $now + 3; $payload['nbf'] = $now + 10; $payload['jti'] = md5(uniqid('JWT') . time()); $base64header = self::base64UrlEncode(json_encode(self::$header, JSON_UNESCAPED_UNICODE)); $base64payload = self::base64UrlEncode(json_encode($payload, JSON_UNESCAPED_UNICODE)); $token = $base64header . '.' . $base64payload . '.' . self::signature($base64header . '.' . $base64payload, $this->secretKey, self::$header['alg']); return $token; } /** * HMACSHA256签名 * https://jwt.io/ 中HMACSHA256签名实现 * @param string $input 为base64UrlEncode(header).".".base64UrlEncode(payload) * @param string $key * @param string $alg 算法方式 * @return mixed */ private static function signature($input, $key, $alg = 'HS256') { $alg_config = array( 'HS256' => 'sha256' ); return self::base64UrlEncode(hash_hmac($alg_config[$alg], $input, $key, true)); } /** * base64UrlEncode https://jwt.io/ 中base64UrlEncode编码实现 * @param string $input 需要编码的字符串 * @return string */ private static function base64UrlEncode($input) { return str_replace('=', '', strtr(base64_encode($input), '+/', '-_')); } /** * 对密钥进行二次加密 * @param $data */ public function signSecret($data) { $data['nonce_str'] = self::createNoncestr(32); $data['timestamp'] = time(); $this->secretKey = self::getSignature($data, $this->app_secret); return $data; } /** * 数据生成签名 * @param array $data 签名数组 * @param string $method 签名方法 * @return bool|string 签名值 */ public static function getSignature($data, $partnerKey, $method = "sha1") { if (!function_exists($method)) { return false; } ksort($data); $buff = ''; foreach ($data as $k => $v) { $buff .= "{$k}={$v}&"; } return $method(strtoupper(md5("{$buff}key={$partnerKey}"))); } /** * 产生随机字符串 * @param int $length 指定字符长度 * @param string $str 字符串前缀 * @return string */ public static function createNoncestr($length = 32, $str = "") { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } /** * 以post方式提交请求 * @param string $url * @param array|string $data * @return bool|mixed */ public static function httpPost($url, $data, $header = null) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); if ($header) { curl_setopt($curl, CURLOPT_HTTPHEADER, self::_buildHeader($header)); // curl_setopt($curl, CURLOPT_HEADER, true); } else { curl_setopt($curl, CURLOPT_HEADER, false); } curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, self::_buildPost($data)); // $response = curl_exec($curl); // $responseInfo = curl_getinfo($curl); // curl_close($curl); list($content, $status) = array(curl_exec($curl), curl_getinfo($curl), curl_close($curl)); return (intval($status["http_code"]) === 200) ? $content : false; } /** * POST数据过滤处理 * @param array $data * @return array */ static private function _buildHeader($data) { $newData = []; if (is_array($data)) { foreach ($data as $key => $value) { $newData[] = $key . ":" . $value; } } return $newData; } /** * POST数据过滤处理 * @param array $data * @return array */ static private function _buildPost(&$data) { if (is_array($data)) { foreach ($data as &$value) { if (is_string($value) && $value[0] === '@' && class_exists('CURLFile', false)) { $filename = realpath(trim($value, '@')); file_exists($filename) && $value = new CURLFile($filename); } } } return $data; } /** * 使用证书,以post方式提交xml到对应的接口url * @param string $url POST提交的内容 * @param array $data 请求的地址 * @param string $ssl_cer 证书Cer路径 | 证书内容 * @param string $ssl_key 证书Key路径 | 证书内容 * @param int $second 设置请求超时时间 * @return bool|mixed */ static public function httpsPost($url, $data, $header = null, $ssl_cer = null, $ssl_key = null, $second = 30) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_TIMEOUT, $second); curl_setopt($curl, CURLOPT_HEADER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); if ($header) { curl_setopt($curl, CURLOPT_HTTPHEADER, $header); } if (!is_null($ssl_cer) && file_exists($ssl_cer) && is_file($ssl_cer)) { curl_setopt($curl, CURLOPT_SSLCERTTYPE, 'PEM'); curl_setopt($curl, CURLOPT_SSLCERT, $ssl_cer); } if (!is_null($ssl_key) && file_exists($ssl_key) && is_file($ssl_key)) { curl_setopt($curl, CURLOPT_SSLKEYTYPE, 'PEM'); curl_setopt($curl, CURLOPT_SSLKEY, $ssl_key); } curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, self::_buildPost($data)); list($content, $status) = array(curl_exec($curl), curl_getinfo($curl), curl_close($curl)); return (intval($status["http_code"]) === 200) ? $content : false; }
PHP经典接口授权校验,你绝对想不到
最新推荐文章于 2024-06-27 19:09:04 发布