auth-json.php 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. <?php
  2. /**
  3. * php 签名样例
  4. */
  5. function isActionAllow($method, $pathname, $query, $headers)
  6. {
  7. $allow = true;
  8. // // TODO 这里判断自己网站的登录态
  9. // if ($!logined) {
  10. // $allow = false;
  11. // return $allow;
  12. // }
  13. // 请求可能带有点所有 action
  14. // acl,cors,policy,location,tagging,lifecycle,versioning,replication,versions,delete,restore,uploads
  15. // 请求跟路径,只允许获取 UploadId
  16. if ($pathname === '/' && !($method === 'get' && isset($query['uploads']))) {
  17. $allow = false;
  18. }
  19. // 不允许前端获取和修改文件权限
  20. if ($pathname !== '/' && isset($query['acl'])) {
  21. $allow = false;
  22. }
  23. // 这里应该根据需要,限制当前站点的用户只允许操作什么样的路径
  24. if ($method === 'delete' && $pathname !== '/') { // 这里控制是否允许删除文件
  25. // TODO 这里控制是否允许删除文件
  26. }
  27. if ($method === 'put' && $pathname !== '/') { // 这里控制是否允许上传和修改文件
  28. // TODO 这里控制是否允许上传和修改文件
  29. }
  30. if ($method === 'get' && $pathname !== '/') { // 这里控制是否获取文件和文件相关信息
  31. // TODO 这里控制是否允许获取文件和文件相关信息
  32. }
  33. return $allow;
  34. }
  35. /*
  36. * 获取签名
  37. * @param string $method 请求类型 method
  38. * @param string $pathname 文件名称
  39. * @param array $query query参数
  40. * @param array $headers headers
  41. * @return string 签名字符串
  42. */
  43. function getAuthorization($method, $pathname, $query, $headers)
  44. {
  45. // 获取个人 API 密钥 https://console.qcloud.com/capi
  46. $SecretId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  47. $SecretKey = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  48. // 整理参数
  49. !$query && ($query = array());
  50. !$headers && ($headers = array());
  51. $method = strtolower($method ? $method : 'get');
  52. $pathname = $pathname ? $pathname : '/';
  53. substr($pathname, 0, 1) != '/' && ($pathname = '/' . $pathname);
  54. // 注意这里要过滤好允许什么样的操作
  55. if (!isActionAllow($method, $pathname, $query, $headers)) {
  56. return 'action deny';
  57. }
  58. // 工具方法
  59. function getObjectKeys($obj)
  60. {
  61. $list = array_keys($obj);
  62. sort($list);
  63. return $list;
  64. }
  65. function obj2str($obj)
  66. {
  67. $list = array();
  68. $keyList = getObjectKeys($obj);
  69. $len = count($keyList);
  70. for ($i = 0; $i < $len; $i++) {
  71. $key = $keyList[$i];
  72. $val = isset($obj[$key]) ? $obj[$key] : '';
  73. $key = strtolower($key);
  74. $list[] = rawurlencode($key) . '=' . rawurlencode($val);
  75. }
  76. return implode('&', $list);
  77. }
  78. // 签名有效起止时间
  79. $now = time() - 1;
  80. $expired = $now + 600; // 签名过期时刻,600 秒后
  81. // 要用到的 Authorization 参数列表
  82. $qSignAlgorithm = 'sha1';
  83. $qAk = $SecretId;
  84. $qSignTime = $now . ';' . $expired;
  85. $qKeyTime = $now . ';' . $expired;
  86. $qHeaderList = strtolower(implode(';', getObjectKeys($headers)));
  87. $qUrlParamList = strtolower(implode(';', getObjectKeys($query)));
  88. // 签名算法说明文档:https://www.qcloud.com/document/product/436/7778
  89. // 步骤一:计算 SignKey
  90. $signKey = hash_hmac("sha1", $qKeyTime, $SecretKey);
  91. // 步骤二:构成 FormatString
  92. $formatString = implode("\n", array(strtolower($method), $pathname, obj2str($query), obj2str($headers), ''));
  93. // 步骤三:计算 StringToSign
  94. $stringToSign = implode("\n", array('sha1', $qSignTime, sha1($formatString), ''));
  95. // 步骤四:计算 Signature
  96. $qSignature = hash_hmac('sha1', $stringToSign, $signKey);
  97. // 步骤五:构造 Authorization
  98. $authorization = implode('&', array(
  99. 'q-sign-algorithm=' . $qSignAlgorithm,
  100. 'q-ak=' . $qAk,
  101. 'q-sign-time=' . $qSignTime,
  102. 'q-key-time=' . $qKeyTime,
  103. 'q-header-list=' . $qHeaderList,
  104. 'q-url-param-list=' . $qUrlParamList,
  105. 'q-signature=' . $qSignature
  106. ));
  107. return $authorization;
  108. }
  109. // 获取前端过来的参数
  110. $inputBody = file_get_contents("php://input");
  111. if ($_SERVER['REQUEST_METHOD'] === 'POST' && $inputBody){
  112. $params = json_decode($inputBody, 1);
  113. $pathname = isset($params['pathname']) ? $params['pathname'] : '/';
  114. $method = isset($params['method']) ? $params['method'] : 'get';
  115. $query = isset($params['query']) ? $params['query'] : array();
  116. $headers = isset($params['headers']) ? $params['headers'] : array();
  117. } else {
  118. $pathname = isset($_GET['pathname']) ? $_GET['pathname'] : '/';
  119. $method = isset($_GET['method']) ? $_GET['method'] : 'get';
  120. $query = isset($_GET['query']) && $_GET['query'] ? json_decode($_GET['query'], 1) : array();
  121. $headers = isset($_GET['headers']) && $_GET['headers'] ? json_decode($_GET['headers'], 1) : array();
  122. }
  123. // 返回数据给前端
  124. header('Content-Type: text/plain');
  125. header('Allow-Control-Allow-Origin: http://127.0.0.1'); // 这里修改允许跨域访问的网站
  126. header('Allow-Control-Allow-Headers: origin,accept,content-type');
  127. $sign = getAuthorization($method, $pathname, $query, $headers);
  128. echo '{"sign":"' . $sign .'"}';