阿里云获取TOKEN
阿里云获取TOKEN
阿里云有sdk,但是看了一下,解压后有10多MB,于是参照官方文档写一个
https://help.aliyun.com/document_detail/113251.html
采坑指南(其他开发语言借鉴)
1. 时间Timestamp
(1)时间格式为 2019-04-18T08:32:31Z ,使用UTC时间,时区:+0。格式:YYYY-MM-DDThh:mm:ssZ。注意时区+0;我们大部分人用的是+8时间,需要-8
(2)时间在有的时候需要urlencode,有的时候不要。我就是有个地方少了urlencode,查了好几个小时
2. 转码 urlencode,percentEncode
function percentEncode($str)
{
// 使用urlencode编码后,将"+","*","%7E"做替换即满足ECS API规定的编码规范
$res = urlencode($str);
$res = str_replace('+', '%20', $res);
$res = str_replace('*', '%2A', $res);
$res = str_replace('%7E', '~', $res);
return $res;
}percentEncode是 使用urlencode编码后,将"+","*","%7E"做替换即满足ECS API规定的编码规范
3. 签名
签名本身不复杂,前面调对了基本上能走通,文档里有几个固定值,根据固定值算签名进行核对即可。
---------------------------------
PHP代码如下,自己增加2个配置文件 config/access.json默认内容为{};config/access.json默认内容为{"ACCESS_KEYID":"MY_ACCESS_KEYID","ACCESS_KEYSECRET":"MY_ACCESS_KEYSECRET"}
<?php
/**
* PHP纯净版 获取阿里云TOKEN
* 作者:野生程序员-杂烧
* www.zashao.com
*/
//error_reporting(E_ALL);
error_reporting(0);
date_default_timezone_set('Asia/Shanghai');//设置时区
define("CONFIG_DIR",dirname(__FILE__)."/config/");
//* token.json,access.json 暂时文本存储json文件,访问量大再更换高速缓存
//* config/access.json默认格式为{} token定时刷新 自动存配置文件,根据时间戳刷新
define("TOKEN_PATH",CONFIG_DIR."token.json");
//* config/access.json默认格式为{"ACCESS_KEYID":"MY_ACCESS_KEYID","ACCESS_KEYSECRET":"MY_ACCESS_KEYSECRET"}
define("ACCESS_PATH",CONFIG_DIR."access.json");
$access_info=json_decode(file_get_contents(ACCESS_PATH),true);
define("ACCESS_KEYID", $access_info["ACCESS_KEYID"]);
define("ACCESS_KEYSECRET",$access_info["ACCESS_KEYSECRET"]);
class AliToken
{
private $AccessKeyId;
private $AccessKeySecret;
private $Timestamp;
private $Timestamp_urlencode; //这里有个坑,需要一个urlencode的时间戳
private $SignatureNonce;
private $Action="CreateToken";
private $Version="2019-02-28";
private $Format="JSON";
private $RegionId="cn-shanghai";
private $SignatureMethod="HMAC-SHA1";
private $SignatureVersion="1.0";
private $parameters;
private $Signature;
function __construct(){
$this->AccessKeyId=ACCESS_KEYID;
$this->AccessKeySecret=ACCESS_KEYSECRET;
}
function create_uuid()
{
$str=time().mt_rand().rand(0,9).rand(0,9).rand(0,9).rand(0,9).rand(0,9);
$md5=md5($str);
$result=substr($md5,0,8)."-".substr($md5,8,4)."-".substr($md5,12,4)."-".substr($md5,16,4)."-".substr($md5,20,12);
return $result;
}
function create_Timestamp()
{
$date=date("Y-m-d\TH:i:s\Z",time()-8*3600);
return $date;
}
function percentEncode($str)
{
// 使用urlencode编码后,将"+","*","%7E"做替换即满足ECS API规定的编码规范
$res = urlencode($str);
//$res = $str;
$res = str_replace('+', '%20', $res);
$res = str_replace('*', '%2A', $res);
$res = str_replace('%7E', '~', $res);
return $res;
}
function createSign()
{
$this->Timestamp=$this->create_Timestamp();
$this->SignatureNonce=$this->create_uuid();
//测试用数据 https://help.aliyun.com/document_detail/113251.html 对照算法检查签名结果用
/*
$this->AccessKeyId="my_access_key_id";
$this->AccessKeySecret="my_access_key_secret";
$this->Timestamp="2019-04-18T08:32:31Z";
$this->SignatureNonce="b924c8c3-6d03-4c5d-ad36-d984d3116788";
*/
$this->Timestamp_urlencode=urlencode($this->Timestamp);
$parameters=array(
"AccessKeyId"=>$this->AccessKeyId
,"Action"=>$this->Action
,"Version"=>$this->Version
,"Format"=>$this->Format
,"RegionId"=>$this->RegionId
,"Timestamp"=>$this->Timestamp
,"SignatureMethod"=>$this->SignatureMethod
,"SignatureVersion"=>$this->SignatureVersion
,"SignatureNonce"=>$this->SignatureNonce
);
ksort($parameters);
$this->parameters=$parameters;
$signStr = "";
foreach ($parameters as $key => $val) {
$signStr .= $key . "=" . urlencode($val) . "&";
}
$signStr = substr($signStr, 0, -1);
$signStr="GET&".$this->percentEncode("/")."&".$this->percentEncode($signStr);
$signStr = base64_encode(hash_hmac('SHA1', $signStr, $this->AccessKeySecret."&", true));
$signStr=$this->percentEncode($signStr);
$this->Signature = $signStr;
}
function new_token()
{
$this->createSign();
$url="http://nls-meta.cn-shanghai.aliyuncs.com/?Signature={$this->Signature}&AccessKeyId={$this->AccessKeyId}&Action={$this->Action}&Format={$this->Format}&RegionId={$this->RegionId}&SignatureMethod={$this->SignatureMethod}&SignatureNonce={$this->SignatureNonce}&SignatureVersion={$this->SignatureVersion}&Timestamp={$this->Timestamp_urlencode}&Version={$this->Version}";
file_put_contents("url.txt",$url);
//exit();
$r=file_get_contents($url);
$data=json_decode($r,true);
$token=$data["Token"]["Id"];
return $token;
}
function get_token()
{
$token_info=json_decode(file_get_contents(TOKEN_PATH),true);
$token_time=intval($token_info["time"]);
//4个小时取一次新token 大概24小时过期,这里一天多取几次问题不大
if(time()-$token_time>4*3600)
{
//伪唯一 可能出现极小极小极小概率重复,以及极小情况接口异常,所以只尝试3次
for($i=1;$i<=3;$i++)
{
$token=$this->new_token();
if($token)
{
break;
}
}
if($token){
//token正常需要缓存 *如果不正常要调试一下,肯定哪里出问题了
$token_info_new=array(
"time"=>time(),
"token"=>$token
);
file_put_contents(TOKEN_PATH,json_encode($token_info_new));
}
}else{
$token=$token_info["token"];
}
return $token;
}
}
$ali=new AliToken();
$token=$ali->get_token();
echo "\r\n\r\n{$token}";
?>
