本文主要介绍如何基于Post Policy的使用规则在服务端通过各种语言代码完成签名,然后通过表单直传数据到OSS。由于服务端签名直传无需将AccessKey暴露在前端页面,相比JavaScript客户端签名直传具有更高的安全性。

流程和源码解析

时序图
  1. 用户向应用服务器请求上传Policy。

    客户端源码中的upload.js文件的以下代码片段的变量serverUrl的值设置为应用服务器的URL。

    // serverUrl是用户获取签名和Policy等信息的应用服务器的URL,请将下面的IP和Port配置为您自己的真实信息。
    serverUrl = 'http://88.88.XX.XX:8888'

    设置完成后,客户端会向该serverUrl发送Get请求来获取需要的信息。

    本场景为服务端签名后直传,不涉及上传回调(callback)。您需要将客户端源码中的upload.js内的'callback' : callbackbody字段注释掉,以关闭上传回调功能。修改示例如下:

    {
      'key' : key + '${filename}',
      'policy': policyBase64,
      'OSSAccessKeyId': accessid,
      // 设置服务端返回200状态码,默认返回204。
      'success_action_status' : '200', 
      // 'callback' : callbackbody,  
      'signature': signature,
    }
  2. 应用服务器返回上传Policy和签名给用户。

    应用服务器侧的签名直传服务会处理客户端发送的Get请求消息,您可以设置对应的代码让应用服务器能够给客户端返回正确的消息。

    以下是签名直传服务返回给客户端消息Body内容的示例:

    {
    "accessid":"LTAI5tBDFVar1hoq****",
    "host":"https://post-test.oss-cn-hangzhou.aliyuncs.com",
    "policy":"eyJleHBpcmF0aW9uIjoiMjAxNS0xMS0wNVQyMDoyMzoyM1oiLCJjxb25kaXRpb25zIjpbWyJjcb250ZW50LWxlbmd0aC1yYW5nZSIsMCwxMDQ4NTc2MDAwXSxbInN0YXJ0cy13aXRoIiwiJGtleSIsInVzZXItZGlyXC8i****",
    "signature":"VsxOcOudx******z93CLaXPz+4s=",
    "expire":1446727949,
    "dir":"user-dirs/"
    }
    Body中的各字段说明如下:
    字段描述
    accessid用户请求的AccessKey ID。
    host用户发送上传请求的域名。
    说明 host不支持自定义域名。
    policy用户表单上传的策略(Policy),Policy为经过Base64编码过的字符串。详情请参见Post Policy
    signature对Policy签名后的字符串。详情请参见Post Signature
    expire由服务器端指定的Policy过期时间,格式为Unix时间戳(自UTC时间1970年01月01号开始的秒数)。
    dir限制上传的文件前缀。
  3. 用户使用Post方法向OSS发送文件上传请求。
    说明
    • 除file表单域外,包含key在内的其他所有表单域的大小均不能超过8 KB。
    • 客户端上传默认同名覆盖,如果您不希望覆盖同名文件,可以在上传请求的header中携带参数x-oss-forbid-overwrite,并指定其值为true。当您上传的文件在OSS中存在同名文件时,该文件会上传失败,并返回FileAlreadyExists错误。
    new_multipart_params = {
         // key表示上传到Bucket内的Object的完整路径,例如exampledir/exampleobject.txtObject,完整路径中不能包含Bucket名称。
         // filename表示待上传的本地文件名称。
         'key' : key + '${filename}',
         'policy': policyBase64,
         'OSSAccessKeyId': accessid,
         // 设置服务端返回状态码为200,不设置则默认返回状态码204。
         'success_action_status' : '200',    
         'signature': signature,
     };

代码示例

服务端签名直传并设置上传回调的各语言版本示例如下:

更多参考

大多数情况下,应用服务器需要了解用户上传了哪些文件以及对应的文件名称等信息。如果上传的是图片,还希望获取图片大小等。此时,您可以通过上传回调方案实现该需求。更多信息,请参见服务器端签名直传并设置上传回调