PHP经典接口授权校验,你绝对想不到

对于开发开放接口有很大的帮助,校验码存于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;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值