Aliyun.php 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. <?php
  2. namespace App\Components\DDNS;
  3. use Arr;
  4. use Http;
  5. use Log;
  6. class Aliyun
  7. {
  8. private static $apiHost = 'https://alidns.aliyuncs.com/';
  9. private static $subDomain;
  10. public function __construct($subDomain)
  11. {
  12. self::$subDomain = $subDomain;
  13. }
  14. public function store($ip, $type)
  15. {
  16. $domainInfo = $this->analysisDomain();
  17. if ($domainInfo) {
  18. return $this->send('AddDomainRecord', ['DomainName' => $domainInfo[0], 'RR' => $domainInfo[1], 'Type' => $type, 'Value' => $ip]);
  19. }
  20. return false;
  21. }
  22. private function analysisDomain()
  23. {
  24. $domainList = $this->domainList();
  25. if ($domainList) {
  26. foreach ($domainList as $domain) {
  27. if (strpos(self::$subDomain, $domain) !== false) {
  28. return [$domain, rtrim(substr(self::$subDomain, 0, -(strlen($domain))), '.')];
  29. }
  30. }
  31. }
  32. return false;
  33. }
  34. public function domainList()
  35. {
  36. $result = $this->send('DescribeDomains');
  37. if ($result) {
  38. $result = $result['Domains']['Domain'];
  39. if ($result) {
  40. return Arr::pluck($result, 'DomainName');
  41. }
  42. }
  43. return false;
  44. }
  45. private function send($action, $data = [])
  46. {
  47. $public = [
  48. 'Format' => 'JSON',
  49. 'Version' => '2015-01-09',
  50. 'AccessKeyId' => sysConfig('ddns_key'),
  51. 'SignatureMethod' => 'HMAC-SHA1',
  52. 'Timestamp' => gmdate("Y-m-d\TH:i:s\Z"), //公共参数Timestamp GMT时间
  53. 'SignatureVersion' => '1.0',
  54. 'SignatureNonce' => str_replace('.', '', microtime(true)), //唯一数,用于防止网络重放攻击
  55. ];
  56. $parameters = array_merge(['Action' => $action], $data, $public);
  57. $parameters['Signature'] = $this->computeSignature($parameters);
  58. $response = Http::asForm()->timeout(15)->post(self::$apiHost, $parameters);
  59. $message = $response->json();
  60. if ($response->failed()) {
  61. if ($message && $message['Code']) {
  62. $error = $message['Message'];
  63. } else {
  64. $error = $response->body();
  65. }
  66. Log::error('[Aliyun - '.$action.'] 请求失败:'.$error);
  67. return false;
  68. }
  69. return $message;
  70. }
  71. // 签名
  72. private function computeSignature($parameters): string
  73. {
  74. ksort($parameters);
  75. $stringToBeSigned = 'POST&%2F&'.urlencode(http_build_query($parameters));
  76. return base64_encode(hash_hmac('sha1', $stringToBeSigned, sysConfig('ddns_secret').'&', true));
  77. }
  78. public function update($ip, $type)
  79. {
  80. $recordId = $this->getRecordId($type);
  81. $domainInfo = $this->analysisDomain();
  82. if ($recordId && $domainInfo) {
  83. return $this->send('UpdateDomainRecord', ['RR' => $domainInfo[1], 'RecordId' => $recordId[0], 'Type' => $type, 'Value' => $ip]);
  84. }
  85. return false;
  86. }
  87. /**
  88. * 域名信息.
  89. *
  90. * @param string|null $type 记录类型,默认为 null
  91. * @return array|false
  92. */
  93. private function getRecordId($type = null)
  94. {
  95. $parameters = ['SubDomain' => self::$subDomain];
  96. if ($type) {
  97. $parameters['Type'] = $type;
  98. }
  99. $records = $this->send('DescribeSubDomainRecords', $parameters);
  100. if ($records && Arr::has($records, 'DomainRecords.Record')) {
  101. $records = $records['DomainRecords']['Record'];
  102. $data = null;
  103. foreach ($records as $record) {
  104. $data[] = $record['RecordId'];
  105. }
  106. return $data ?: false;
  107. }
  108. return false;
  109. }
  110. public function destroy($type)
  111. {
  112. $records = $this->getRecordId($type);
  113. if ($records) {
  114. $count = 0;
  115. foreach ($records as $record) {
  116. $result = $this->send('DeleteDomainRecord', ['RecordId' => $record]);
  117. if ($result) {
  118. $count++;
  119. }
  120. }
  121. return $count;
  122. }
  123. return false;
  124. }
  125. }