Aliyun.php 4.0 KB

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