阿里云获取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}"; ?>