LiTry

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

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

 

阿里云签名代码:

 1 <?php
 2 use RingCentral\Psr7\Response;
 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} \t ${host}/${dir}${1} \t ${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 ~]#

 

分类:

技术点:

相关文章: