通过Shell方式上传文件到阿里云OSS

 首先使用阿里云函数计算进行签名,避免Aliyun AccessId/AccessKey 暴露在外面,造成安全风险。

使用者上传文件的逻辑是:
1. 先获取上传oss的 policy 及签名
2. 然后根据拿到签名直接上传到aliyun OSS

阿里云签名代码:

 1 <?php
 2 use RingCentralPsr7Response;
 3 
 4 function gmt_iso8601($time) {
 5     $dtStr = date("c", $time);
 6     $mydatetime = new DateTime($dtStr);
 7     $expiration = $mydatetime->format(DateTime::ISO8601);
 8     $pos = strpos($expiration, '+');
 9     $expiration = substr($expiration, 0, $pos);
10     return $expiration."Z";
11 }
12 
13 function oss_fun($auth){
14    /*
15     这里是鉴权,校验失败直接返回401,不做分享
16     return json_encode(['status'=>401]);
17   */
18   //阿里云官方提供的秘钥
19     $id= 'aliyun accessid';
20     $key= 'aliyun accesskey';
21     $host = 'http://oss-host.domain.com';
22     //$host = 'https://oss-host.oss-cn-hangzhou.aliyuncs.com';
23     $rand_str = rand_str();
24 
25     $dir = 'public-dir-7day-delete/'.date("Ymd-His",time()).'_'.$rand_str.'/';
26 
27     $now = time();
28     $expire = 180; //设置该policy超时时间是180s. 即这个policy过了这个有效时间,将不能访问
29     $end = $now + $expire;
30     $expiration = gmt_iso8601($end);
31 
32     //最大文件大小.当前50MB与web页面相同
33     $condition = array(0=>'content-length-range', 1=>0, 2=>1024*1024*50);
34     $conditions[] = $condition;
35 
36     //表示用户上传的数据,必须是以$dir开始, 不然上传会失败,这一步不是必须项,只是为了安全起见,防止用户通过policy上传到别人的目录
37     $start = array(0=>'starts-with', 1=>'$key', 2=>$dir);
38     $conditions[] = $start;
39 
40     $arr = array('expiration'=>$expiration,'conditions'=>$conditions);
41     $policy = json_encode($arr);
42     $base64_policy = base64_encode($policy);
43     $string_to_sign = $base64_policy;
44     $signature = base64_encode(hash_hmac('sha1', $string_to_sign, $key, true));
45 
46     $response = array();
47     $response['accessid'] = $id;
48     $response['host'] = $host;
49     $response['policy'] = $base64_policy;
50     $response['signature'] = $signature;
51     $response['expire'] = $end;
52     //这个参数是设置用户上传指定的前缀
53     $response['dir'] = $dir;
54     $response['id'] = $rand_str;
55 
56     return json_encode(['status'=>200,'data'=>$response]);
57 }
58 
59 
60 function rand_str( $length = 32 ){
61     $str='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
62     $randStr = str_shuffle($str);//打乱字符串
63     $rands= substr($randStr,0,$length);//substr(string,start,length);返回字符串的一部分
64     return $rands;
65 }
66 function handler($request, $context): Response{
67 
68     $body       = $request->getBody()->getContents();
69     $queries    = $request->getQueryParams();
70     $method     = $request->getMethod();
71     $headers    = $request->getHeaders();
72     $path       = $request->getAttribute('path');
73     $requestURI = $request->getAttribute('requestURI');
74     $clientIP   = $request->getAttribute('clientIP');
75 
76     $auth = isset($headers['Authorization']) ? $headers['Authorization'][0]:null;
77     return new Response(
78         200,
79         array(
80             'Content-Type' => 'application/json; charset=utf-8',
81         ),
82         oss_fun($auth)
83     );
84 }
View Code

编写 shell ,用于快速上传到阿里云oss平台:

 1 #!/bin/bash
 2 
 3 # jq -h >/dev/null 2>&1 ; if [ $? -ne 0 ]; then echo "Need jq";exit; fi
 4 jq -h >/dev/null 2>&1 || { echo "Need jq";exit; }
 5 
 6 function upload_file(){
 7 
 8     #oss=$(curl -s http://root:password@fc.domain.com/upload2oss)#鉴权
 9     oss=$(curl -s http://fc.domain.com/upload2oss) #获取签名的json
10     #echo $oss | python -m json.tool
11     startTime_s=`date +%s.%N`
12     dir=`echo $oss | jq .data.dir | sed s/"//g`
13     host=`echo $oss | jq .data.host | sed s/"//g`
14     policy=`echo $oss | jq .data.policy | sed s/"//g`
15     accessid=`echo $oss | jq .data.accessid | sed s/"//g`
16     signature=`echo $oss | jq .data.signature | sed s/"//g`
17 
18     curl -XPOST -sk ${host} 
19         -F "policy=${policy}" 
20         -F "Signature=${signature}" 
21         -F "success_action_status=200" 
22         -F "OSSAccessKeyId=${accessid}" 
23         -F "x-oss-object-acl=public-read" 
24         -F "key=${dir}${1}" 
25         -F "file=@${2}" 
26 
27     endTime_s=`date +%s.%N`
28     runTime=`echo $endTime_s $startTime_s | awk '{print $1-$2}'`
29     status=`curl -sI "${host}/${dir}${1}" | awk 'NR==1{print $2}'`
30 
31     if [ "${status}"x == "200"x ]; then
32         echo -e "${2} 	 ${host}/${dir}${1} 	 ${runTime}s"
33     else
34         echo "Upload failed:  ${status}"
35     fi
36 }
37 
38 for i in $*; do   
39     if [ ! -f ${i} ]; then
40         echo "${i} no file"; continue;
41     else
42         upload_file ${i##*/} ${i}
43     fi
44 done 

 效果如下:

1 [litry@HK ~]# ./oss.sh oss.sh docker.sh 
2 oss.sh      http://oss-host.domain.com/public-dir-7day-delete/20201009-150007_lQGImxc7dtrkXqCh/oss.sh      1.91704s
3 docker.sh      http://oss-host.domain.com/public-dir-7day-delete/20201009-150009_QBg0W5JFbelL26GN/docker.sh      0.498585s
4 [litry@HK ~]#
TryEverything
原文地址:https://www.cnblogs.com/LiTry/p/13789225.html