Uploadoss.php 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <?php
  2. namespace app\api\controller;
  3. use think\facade\Request;
  4. use DateTime;
  5. class Uploadoss extends Base
  6. {
  7. /*
  8. *
  9. */
  10. private function gmt_iso8601($time)
  11. {
  12. $dtStr = date("c", $time);
  13. $mydatetime = new DateTime($dtStr);
  14. $expiration = $mydatetime->format(DateTime::ISO8601);
  15. $pos = strpos($expiration, '+');
  16. $expiration = substr($expiration, 0, $pos);
  17. return $expiration . "Z";
  18. }
  19. /*
  20. * 后端直传oss文件
  21. */
  22. public function oss_signature()
  23. {
  24. $cate = input('cate');
  25. $id = config('app.ali_oss_access_key_id');
  26. $key = config('app.ali_oss_access_key_secret');
  27. // $host的格式为 bucketname.endpoint,请替换为您的真实信息。
  28. $host = 'https://' . config('app.ali_oss_bindurl');
  29. // $callbackUrl为上传回调服务器的URL,请将下面的IP和Port配置为您自己的真实URL信息。
  30. $callbackUrl = "https://" . $_SERVER['HTTP_HOST'] . "/api/uploadoss/osscallback.html";
  31. if ($cate) {
  32. $dir = $cate . '/'; // 用户上传文件时指定的前缀。
  33. }
  34. $callback_param = array(
  35. 'callbackUrl' => $callbackUrl,
  36. 'callbackBody' => 'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}',
  37. 'callbackBodyType' => "application/x-www-form-urlencoded"
  38. );
  39. $callback_string = json_encode($callback_param);
  40. $base64_callback_body = base64_encode($callback_string);
  41. $now = time();
  42. $expire = 30; //设置该policy超时时间是10s. 即这个policy过了这个有效时间,将不能访问。
  43. $end = $now + $expire;
  44. $expiration = $this->gmt_iso8601($end);
  45. //最大文件大小.用户可以自己设置
  46. $condition = array(0 => 'content-length-range', 1 => 0, 2 => 1048576000);
  47. $conditions[] = $condition;
  48. // 表示用户上传的数据,必须是以$dir开始,不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录。
  49. $start = array(0 => 'starts-with', 1 => '$key', 2 => $dir);
  50. $conditions[] = $start;
  51. $arr = array('expiration' => $expiration, 'conditions' => $conditions);
  52. $policy = json_encode($arr);
  53. $base64_policy = base64_encode($policy);
  54. $string_to_sign = $base64_policy;
  55. $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));
  56. $response = array();
  57. $response['accessid'] = $id;
  58. $response['host'] = $host;
  59. $response['policy'] = $base64_policy;
  60. $response['signature'] = $signature;
  61. $response['expire'] = $end;
  62. $response['callback'] = $base64_callback_body;
  63. $response['dir'] = $dir; // 这个参数是设置用户上传文件时指定的前缀。
  64. $response['callback2'] = $callbackUrl;
  65. return json($response);
  66. }
  67. public function osscallback()
  68. {
  69. // 1.获取OSS的签名header和公钥url header
  70. $authorizationBase64 = "";
  71. $pubKeyUrlBase64 = "";
  72. /*
  73. * 注意:如果要使用HTTP_AUTHORIZATION头,你需要先在apache或者nginx中设置rewrite,以apache为例,修改
  74. * 配置文件/etc/httpd/conf/httpd.conf(以你的apache安装路径为准),在DirectoryIndex index.php这行下面增加以下两行
  75. RewriteEngine On
  76. RewriteRule .* - [env=HTTP_AUTHORIZATION:%{HTTP:Authorization},last]
  77. * */
  78. header("Content-Type: application/json");
  79. $data = array("Status" => "Ok");
  80. echo json_encode($data);
  81. if (isset($_SERVER['HTTP_AUTHORIZATION'])) {
  82. $authorizationBase64 = $_SERVER['HTTP_AUTHORIZATION'];
  83. }
  84. if (isset($_SERVER['HTTP_X_OSS_PUB_KEY_URL'])) {
  85. $pubKeyUrlBase64 = $_SERVER['HTTP_X_OSS_PUB_KEY_URL'];
  86. }
  87. if ($authorizationBase64 == '' || $pubKeyUrlBase64 == '') {
  88. header("http/1.1 403 Forbidden");
  89. exit();
  90. }
  91. // 2.获取OSS的签名
  92. $authorization = base64_decode($authorizationBase64);
  93. // 3.获取公钥
  94. $pubKeyUrl = base64_decode($pubKeyUrlBase64);
  95. $ch = curl_init();
  96. curl_setopt($ch, CURLOPT_URL, $pubKeyUrl);
  97. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  98. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 10);
  99. $pubKey = curl_exec($ch);
  100. if ($pubKey == "") {
  101. header("http/1.1 403 Forbidden");
  102. exit();
  103. }
  104. // 4.获取回调body
  105. $body = file_get_contents('php://input');
  106. // 5.拼接待签名字符串
  107. $authStr = '';
  108. $path = $_SERVER['REQUEST_URI'];
  109. $pos = strpos($path, '?');
  110. if ($pos === false) {
  111. $authStr = urldecode($path) . "\n" . $body;
  112. } else {
  113. $authStr = urldecode(substr($path, 0, $pos)) . substr($path, $pos, strlen($path) - $pos) . "\n" . $body;
  114. }
  115. // 6.验证签名
  116. $ok = openssl_verify($authStr, $authorization, $pubKey, OPENSSL_ALGO_MD5);
  117. if ($ok == 1) {
  118. header("Content-Type: application/json");
  119. } else {
  120. header("http/1.1 403 Forbidden");
  121. exit();
  122. }
  123. }
  124. }