添加链接
link管理
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
- 前端要上传文件,找后端要签名 - 后端将签名给到前端,签名里面可以设置各种参数(上传目录,文件大小,类型,上传有效期,回调等) - 前端拿到这些参数签名后,构造 `from` 表单,将相应的 `key`,`value` 赋值后上传到指定的URL上 - 上传成功后,S3会根据签名里面设置的回调路由或状态码给到前端,前端来判断成功或失败(也可以回调到指定的后端接口来判断是否成功) ## 图解: ![](https://s2.loli.net/2022/06/15/KZ2Iqz9VBoyUlYC.png) 1. 用户从 Web 浏览器访问您的页面。 1. 您的网页包含一个 HTML 表单,其中包含用户将内容上传到 Amazon S3 所需的所有信息。 1. 用户通过 Web 浏览器将内容上传到 Amazon S3。 ## 验签图解 ![](https://s2.loli.net/2022/06/15/L7nac1gXYA6rRy9.png) # 附录-代码示例 ## 参考文档 参考文档在代码里面有,详情看代码 ## 服务端代码 * Description: 后端签名,前端直传S3 * Author: Shuxiaoyuan * Email: [email protected] * DateTime: 2022/5/10 15:05 * @param Request $request * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\Contracts\View\View * @throws \Exception public function testS3UploadHtml(Request $request) // 一个是前端 HTML 表单中需要的字段,一个是后端 policy 的验签 // HTML 表单里面的字段,都由后端 policy 验签中获得 // HTML 表单字段:https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/sigv4-HTTPPOSTForms.html $html_form = [ // 非必须,默认 private 'acl' => 'private', // 必须,上传文件的键名,如果要使用用户提供的文件本身的文件名,请使用 ${filename} 变量,如:/data/user1/${filename} 'key' => '/data/s3/' . date('Ymd') . '/' . Str::random(32), // base64编码的安全策略,描述请求中允许的内容。 // 没有安全策略的请求被认为是匿名的,并且只能在可公开写入的bucket上成功。 'policy' => '', // 非必须:成功上载后客户端重定向到的URL。 'success_action_redirect' => 'https://www.shuxiaoyuan.com/', // 非必须,如果未指定 success_action_redirect 则在成功上载时返回给客户端的 http 状态码,有效值为200、201或204(默认值)。 'success_action_status' => 200, // 用于验证请求的签名算法。对于 AWS 签名版本4,值为 AWS4-HMAC-SHA256 'x-amz-algorithm' => 'AWS4-HMAC-SHA256', // 用于计算签名的凭据。它提供访问密钥 ID 和范围信息,标识签名对其有效的区域和服务。这应该与您在计算签名计算的签名密钥时使用的范围相同。 // 它是以下形式的字符串:////aws4_request // 例如:AKIAIOSFODNN7EXAMPLE/20130728/us-east-1/s3/aws4_request 'x-amz-credential' => $this->key . '/' . date('Ymd') . '/' . $this->region . '/s3/aws4_request', // ISO8601 格式字符串中指定的日期值。例如,20130728T000000Z。日期必须与您在创建签名计算签名密钥时使用的日期相同。 // 如果请求中包含 POST 策略文档,则这是必需的。 'x-amz-date' => '20220511T000000Z', // 非必须:Amazon DevPay使用的安全令牌和会话凭据。更多看文档 'x-amz-security-token' => '', // (AWS签名版本4)安全策略的HMAC-SHA256哈希。 'x-amz-signature' => '', // 非必须:以该前缀开头的字段名是用户定义的元数据。每一个都作为一组键值对存储和返回。Amazon S3不验证或解释用户定义的元数据。 // 更多详细,看文档 'x-amz-meta-*' => '', // 非必须:请参见POST对象(其他x-amz-*标题请参见POST对象)。 'x-amz-*' => '', // 必须:文件或文本内容。文件或内容必须是表单中的最后一个字段。一次不能上载多个文件。 'file' => '', // POST 策略:https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/API/sigv4-HTTPPOSTConstructPolicy.html $post_policy = [ // 非必须:指定表单提交中必须使用的 ACL 值。默认 private,需要存储桶开启 acl 'acl' => 'private', // 桶:指定可接受的存储桶名称。 'bucket' => $this->bucket, // 上传内容的最小和最大允许大小,示例 1M~100M 'content-length-range' => ["content-length-range", 1024 * 1024, 1024 * 1024 * 100], // 上传文件,可以是目录,可以是自定义文件名,自定义需要用变量代替 'key' => 'images/' . date('Ymd') . '/' . Str::random('32'), // 成功上传后客户端重定向到的 URL。 'success_action_redirect' => 'https://www.shuxiaoyuan.com/', // success_action_redirect 如果不指定,上传成功返回给客户端的状态码,默认 204 'success_action_status' => 200, // 签名计算时必须使用的签名算法。对于 AWS 签名版本 4,该值为 AWS4-HMAC-SHA256 'x-amz-algorithm' => 'AWS4-HMAC-SHA256', // 用于计算签名的凭据。它提供访问密钥 ID 和范围信息,标识签名对其有效的区域和服务。这应该与您在计算签名计算的签名密钥时使用的范围相同。 // 它是以下形式的字符串:////aws4_request // 例如:AKIAIOSFODNN7EXAMPLE/20130728/us-east-1/s3/aws4_request 'x-amz-credential' => $this->key . '/' . date('Ymd') . '/' . $this->region . '/s3/aws4_request', // ISO8601 格式字符串中指定的日期值。例如,20130728T000000Z。日期必须与您在创建签名计算签名密钥时使用的日期相同。 // 如果请求中包含 POST 策略文档,则这是必需的。 'x-amz-date' => '20220511T000000Z', // Amazon DevPay 安全令牌。 'x-amz-security-token' => '', // 用户指定的元数据。 'x-amz-meta-*' => '', // 请参阅 POST 对象(其他 标头的POST 对象x-amz-* 'x-amz-*' => '', // 签名规则:https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-authentication-HTTPPOST.html // 签名示例:https://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-post-example.html // 签名第一步:组装签名字符串(post 策略) $time = time(); // 拼接 x-amz-credential $credential_params = [ $this->key, gmdate('Ymd', $time), $this->region, 's3', 'aws4_request', $credential = implode('/', $credential_params); // 这样就是指定了文件名,如果不指定文件名,想用文件本身的文件名,就是 images/20220606/${filename} $key = 'images/' . date('Ymd') . '/' . Str::random('32'); // POST 策略 $policy = [ 'expiration' => gmdate('Y-m-d\TH:i:s\Z', strtotime('+2 hours', $time)), 'conditions' => [ ['bucket' => $this->bucket], ['starts-with', '$key', $key], ['x-amz-credential' => $credential], ['x-amz-algorithm' => 'AWS4-HMAC-SHA256'], ['x-amz-date' => gmdate('Ymd\THis\Z', $time)], // 手动签名第二步:组装签名key $dateKey = hash_hmac("sha256", $credential_params[1], 'AWS4' . $this->secret, true); $dateRegionKey = hash_hmac("sha256", $this->region, $dateKey, true); $dateRegionServiceKey = hash_hmac("sha256", $credential_params[3], $dateRegionKey, true); $signingKey = hash_hmac("sha256", $credential_params[4], $dateRegionServiceKey, true); // 手动签名第三步:签名 $stringToSign = base64_encode(json_encode($policy)); $signature1 = hash_hmac("sha256", $stringToSign, $signingKey); $signature = $signature1; // 前端 from 表单需要的数据 $data = [ // 亚马逊中国上传地址:https://桶名.s3.区域(一般为cn-north-1).amazonaws.com.cn/ // 亚马逊全球上传地址:https://桶名.s3.amazonaws.com/ 'url' => 'https://' . $this->bucket . '.s3.' . $this->region . '.amazonaws.com.cn/', 'bucket' => $this->bucket, 'key' => $key, 'x_amz_credential' => $credential, 'x_amz_algorithm' => 'AWS4-HMAC-SHA256', 'x_amz_date' => gmdate('Ymd\THis\Z', $time), 'policy_base64' => $encodedPolicy, 'signature' => $signature, return view('s3.upload', ['data' => $data]); ## HTML 代码
Key to upload:必须, 要使用用户提供的文件名,请使用 ${filename} 变量。 例如,如果您上传一个文件 photo1.jpg 并指定 /user/user1/${filename} 为键名, 则该文件将存储为/user/user1/photo1.jpg

Credential:如果请求中包含政策文件,则这是必需的。

Algorithm:如果请求中包含政策文件,则此字段是必需的

Date:如果请求中包含政策文件,则这是必需的。

Policy:描述请求中允许的内容的 base64 编码的安全策略。对于经过身份验证的请求,需要策略

Signature:如果请求中包含政策文件,则此字段是必需的

File:文件或内容必须是表单中的最后一个字段,您一次不能上传多个文件


内容版权声明:本文为舒孝元原创文章,转载无需和我联系,但请注明来自 舒孝元博客:https://www.shuxiaoyuan.com/info/97

联系邮箱:[email protected]