全部產品
Search
文件中心

Object Storage Service:Ruby

更新時間:Feb 28, 2024

本文以Ruby語言為例,講解在服務端通過Ruby程式碼完成簽名,並且設定上傳回調,然後通過表單直傳資料到OSS。

前提條件

  • 應用伺服器對應的網域名稱可通過公網訪問。
  • 確保應用伺服器已經安裝Ruby 2.0以上版本(執行ruby -v命令進行查看)。
  • 確保PC端瀏覽器支援JavaScript。

步驟1:配置應用伺服器

  1. 下載應用伺服器源碼(Ruby版本)。
  2. 以Ubuntu 16.04為例,將檔案解壓到/home/aliyun/aliyun-oss-appserver-ruby目錄下。
  3. 進入該目錄,開啟源碼檔案appserver.rb,修改如下程式碼片段:
    # 請填寫您的AccessKeyId。
    $access_key_id = '<yourAccessKeyId>'
    
    # 請填寫您的AccessKeySecret。
    $access_key_secret = '<yourAccessKeySecret>'
    
    # $host的格式為bucketname.endpoint,請替換為您的真實資訊。
    $host = 'https://bucket-name.oss-cn-hangzhou.aliyuncs.com';
    
    # $callbackUrl為上傳回調伺服器的URL,請將下面的IP和Port配置為您自己的真實資訊。
    $callback_url = "http://192.0.2.0:8888";
    
    # 使用者上傳檔案時指定的首碼。
    $upload_dir = 'user-dir-prefix/'
    • $access_key_id:設定您的AccessKeyId。
    • $access_key_secret:設定您的AessKeySecret。
    • $host:格式為https://bucketname.endpoint,例如https://bucket-name.oss-cn-hangzhou.aliyuncs.com。關於Endpoint的介紹,請參見Endpoint訪問網域名稱
    • $callback_url:設定上傳回調URL,即回調伺服器位址,用於處理應用伺服器與OSS之間的通訊。OSS會在檔案上傳完成後,把檔案上傳資訊通過此回調URL發送給應用伺服器。本例中修改為:$callback_url="http://192.0.2.0:1234";
    • $upload_dir:若要設定上傳到OSS檔案的首碼則需要配置此項,否則置空即可。

步驟2:配置用戶端

  1. 下載用戶端源碼
  2. 將檔案解壓,本樣本解壓至D:\aliyun\aliyun-oss-appserver-js目錄。
  3. 進入該目錄,開啟upload.js檔案,找到下面的代碼語句:
    // serverUrl是使用者擷取簽名和Policy等資訊的應用伺服器的URL,請將下面的IP和Port配置為您自己的真實資訊。
    serverUrl = 'http://192.0.2.0:8888'
  4. severUrl改成應用伺服器的地址,用戶端可以通過它擷取簽名直傳Policy等資訊。如本例中可修改為:serverUrl = 'http://192.0.2.0:1234'

步驟3:修改CORS

用戶端進行表單直傳到OSS時,會從瀏覽器向OSS發送帶有Origin的請求訊息。OSS對帶有Origin頭的請求訊息會進行跨域規則(CORS)的驗證。因此需要為Bucket設定跨域規則以支援Post方法。

  1. 登入OSS管理主控台

  2. 單擊Bucket 列表,然後單擊目標Bucket名稱。

  3. 在左側導覽列,選擇資料安全 > 跨網域設定
  4. 單擊建立規則,配置如下圖所示。
    說明 為了您的資料安全,實際使用時,來源建議填寫實際允許訪問的網域名稱。更多配置資訊請參見設定跨域訪問

步驟 4:體驗上傳回調

  1. 啟動應用伺服器。
    /home/aliyun/aliyun-oss-appserver-ruby目錄下,執行ruby appserver.rb 192.0.2.0 1234命令啟動應用伺服器。
    說明 請將IP和連接埠改成您配置的應用伺服器的IP和連接埠。
  2. 啟動用戶端。
    在PC端的用戶端源碼目錄中,開啟index.html檔案。
    重要

    index.html檔案不保證相容IE 10以下版本瀏覽器,若使用IE 10以下版本瀏覽器出現問題時,您需要自行調試。

  3. 上傳檔案。
    單擊選擇檔案,選擇指定類型的檔案後,單擊開始上傳。上傳成功後,顯示回調伺服器返回的內容。

應用伺服器核心代碼解析

應用伺服器源碼包含了簽名直傳服務和上傳回調服務兩個功能。

  • 簽名直傳服務

    簽名直傳服務響應用戶端發送給應用伺服器的GET訊息,程式碼片段如下:

    def get_token()
        expire_syncpoint = Time.now.to_i + $expire_time
    
        expire = Time.at(expire_syncpoint).utc.iso8601()
        response.headers['expire'] = expire
    
        policy_dict = {}
        condition_arrary = Array.new
        array_item = Array.new
        array_item.push('starts-with')
        array_item.push('$key')
        array_item.push($upload_dir)
        condition_arrary.push(array_item)
        policy_dict["conditions"] = condition_arrary
        policy_dict["expiration"] = expire
        policy = hash_to_jason(policy_dict)
        policy_encode = Base64.strict_encode64(policy).chomp;
        h = OpenSSL::HMAC.digest('sha1', $access_key_secret, policy_encode)
        hs = Digest::MD5.hexdigest(h)
        sign_result = Base64.strict_encode64(h).strip()
    
        callback_dict = {}
        callback_dict['callbackBodyType'] = 'application/x-www-form-urlencoded';
        callback_dict['callbackBody'] = 'filename=${object}&size=${size}&mimeType=${mimeType}&height=${imageInfo.height}&width=${imageInfo.width}';
        callback_dict['callbackUrl'] = $callback_url;
        callback_param = hash_to_jason(callback_dict)
        base64_callback_body = Base64.strict_encode64(callback_param);
    
        token_dict = {}
        token_dict['accessid'] = $access_key_id
        token_dict['host'] = $host
        token_dict['policy'] = policy_encode
        token_dict['signature'] = sign_result 
        token_dict['expire'] = expire_syncpoint
        token_dict['dir'] = $upload_dir
        token_dict['callback'] = base64_callback_body
        response.headers["Access-Control-Allow-Methods"] = "POST"
        response.headers["Access-Control-Allow-Origin"] = "*"
        result = hash_to_jason(token_dict)
    
        result
    end
    
    get '/*' do
      puts "********************* GET "
      get_token()
    end
  • 上傳回調服務

    上傳回調服務響應OSS發送給應用伺服器的POST訊息,程式碼片段如下:

    post '/*' do
      puts "********************* POST"
      pub_key_url = Base64.decode64(get_header('x-oss-pub-key-url'))
      pub_key = get_public_key(pub_key_url)
      rsa = OpenSSL::PKey::RSA.new(pub_key)
    
      authorization = Base64.decode64(get_header('authorization'))
      req_body = request.body.read
      if request.query_string.empty? then
        auth_str = CGI.unescape(request.path) + "\n" + req_body
      else
        auth_str = CGI.unescape(request.path) + '?' + request.query_string + "\n" + req_body
      end
    
      valid = rsa.public_key.verify(
        OpenSSL::Digest::MD5.new, authorization, auth_str)
    
      if valid
        #body({'Status' => 'OK'}.to_json)
        body(hash_to_jason({'Status' => 'OK'}))
      else
        halt 400, "Authorization failed!"
      end
    end

    更多詳情請參見API文檔Callback