阿里云CDN PHP版本签名机制代码

2018年04月15日 1706点热度 3人点赞 0条评论

阿里云CDN的API文档关于调用方式的说明在这里:

>>help.aliyun.com/document_detail/27149.html

稍微复杂的就是它的签名机制,文档中只给出了python和java的示例代码,下面是我写的一个简单的php版本代码。

注意 如果本程序无法正常运行,请尝试阿里云PHP版本的sdk

>>github.com/aliyun/aliyun-openapi-php-sdk


AliCdn.class.php

<?php
/**
 * Author: kamino
 * CreateTime: 2018/4/14,下午 11:07
 * Description: 阿里云CDN API签名机制
 * Version: v1.0
 */

class AliCdn {

	private $config = array();
	private $response = "";

	/*
	 * 初始化类
	 * @param Array
	 */
	function __construct( $config = array() ) {
		date_default_timezone_set( "UTC" );
		if ( ! isset( $config["Format"] ) ) {
			$config["Format"] = "XML";
		}
		if ( ! isset( $config["AccessKeyId"] ) || ! isset( $config["AccessKeySecret"] ) ) {
			die( "miss important value" );
		}
		$this->config["Format"]           = $config["Format"];
		$this->config["AccessKeyId"]      = $config["AccessKeyId"];
		$this->config["AccessKeySecret"]  = $config["AccessKeySecret"];
		$this->config["Version"]          = "2014-11-11";
		$this->config["SignatureMethod"]  = "HMAC-SHA1";
		$this->config["Timestamp"]        = date( "Y-m-d\TH:i:s\Z" );
		$this->config["SignatureVersion"] = "1.0";
	}

	/*
	 * 添加参数
	 * @param Array
	 * @return $this
	 */
	function addAction( $content = array() ) {
		foreach ( $content AS $name => $value ) {
			$this->config[ $name ] = $value;
		}

		return $this;
	}

	/*
	 * 获取请求值
	 * @return String
	 */
	function getResponse() {
		$this->config["SignatureNonce"]   = time() . "-" . rand( 0, 9999999999 );
		$this->main();

		return $this->response;
	}

	private function main() {
		//a.1 按照参数名称的字典顺序对请求中所有的请求参数(包括文档中描述的“公共请求参数”和给定了的请求接口的自定义参数,但不能包括“公共请求参数”中提到Signature参数本身)进行排序。
		@ksort( $this->config );
		$list = array();
		foreach ( $this->config AS $name => $value ) {
			//a.2 对每个请求参数的名称和值进行编码。名称和值要使用UTF-8字符集进行URL编码
			//a.3 对编码后的参数名称和值使用英文等号(=)进行连接。
			$list[] = $this->percentEncode( $name ) . "=" . $this->percentEncode( $value );
		}
		//a.4 再把英文等号连接得到的字符串按参数名称的字典顺序依次使用&符号连接,即得到规范化请求字符串。
		$queryString = implode( "&", $list );
		//b 使用上一步构造的规范化字符串按照下面的规则构造用于计算签名的字符串
		$toSign = "GET&";
		$toSign .= $this->percentEncode( "/" ) . "&";
		$toSign .= $this->percentEncode( $queryString );
		//c 按照RFC2104的定义,使用上面的用于签名的字符串计算签名HMAC值。注意:计算签名时使用的Key就是用户持有的Access Key Secret并加上一个“&”字符(ASCII:38),使用的哈希算法是SHA1。
		//d 按照Base64编码规则把上面的HMAC值编码成字符串,即得到签名值(Signature)。
		$Signature = base64_encode( hash_hmac( "SHA1", $toSign, $this->config["AccessKeySecret"] . "&", true ) );
		//e 将得到的签名值作为Signature参数添加到请求参数中,即完成对请求签名的过程。
		$url = "https://cdn.aliyuncs.com/?";
		foreach ( $this->config AS $n => $v ) {
			$url .= "$n=$v&";
		}
		$url            .= "Signature=$Signature";
		$this->response = $this->curlGet( $url );
	}

	private function curlGet( $url ) {
		$ch = curl_init();
		curl_setopt( $ch, CURLOPT_URL, $url );
		curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
		curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );
		$result = curl_exec( $ch );
		curl_close( $ch );

		return $result;
	}

	private function percentEncode( $str ) {
		return str_replace( "%7E", "~", str_replace( "+", "%20", urlencode( $str ) ) );
	}
}

demo.php

<?php
/**
 * Author: kamino
 * CreateTime: 2018/4/15,上午 10:53
 * Description: a demo
 * Version:
 */

require_once __DIR__ . "/lib/AliCdn.class.php";

$config = array(
	"Format"          => "JSON",
	"AccessKeyId"     => "yourId",
	"AccessKeySecret" => "yourSecret"
);

$api = new AliCdn( $config );

$content = array(
	"Action" => "DescribeCdnService",

);

$response = $api->addAction( $content )->getResponse();

print_r( $response );

 

AIKAMINO

暂无