通過Elastic Compute Service編寫網頁時,可能需要引用私人許可權的圖片檔案。您可以通過SDK或ossutil產生較長到期時間的簽名URL,以便在指定時間段內訪問這些檔案。為避免圖片被盜用,還需對圖片所在的Bucket通過配置Referer來設定防盜鏈,以保護圖片所在的Bucket。
步驟一:產生簽名URL
出於安全考慮,OSS台中預設URL的有效時間為3600秒,最大值為32400秒。若需時效超過最大值32400秒的檔案URL,請使用命令列工具ossutil或OSS SDK。
以下樣本用於為儲存空間examplebucket下的檔案exampleobject.png組建檔案URL,並指定該簽名URL在30天內可有效訪問。
使用命令列工具ossutil
ossutil sign oss://examplebucket/exampleobject.png --timeout 2592000
在運行以下範例程式碼之前,請確保已設定環境變數OSS_ACCESS_KEY_ID和OSS_ACCESS_KEY_SECRET。
使用阿里雲SDK
import com.aliyun.oss.*;
import com.aliyun.oss.common.auth.*;
import java.net.URL;
import java.util.Date;
public class Demo {
public static void main(String[] args) throws Throwable {
// Endpoint以華東1(杭州)為例,其他Region請按實際情況填寫。
String endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 強烈建議不要把訪問憑證儲存到工程代碼裡,否則可能導致訪問憑證泄露,威脅您帳號下所有資源的安全。本程式碼範例以從環境變數中擷取訪問憑證為例。
EnvironmentVariableCredentialsProvider credentialsProvider = CredentialsProviderFactory.newEnvironmentVariableCredentialsProvider();
// 填寫Bucket名稱,例如examplebucket。
String bucketName = "examplebucket";
// 填寫Object完整路徑,例如exampleobject.png。Object完整路徑中不能包含Bucket名稱。
String objectName = "exampleobject.png";
// 建立OSSClient執行個體。
OSS ossClient = new OSSClientBuilder().build(endpoint, credentialsProvider);
try {
// 設定簽名URL到期時間,單位為秒,本樣本以設定到期時間為30天為例。您可以根據實際業務情境,設定合理的到期時間。
// 擷取目前時間的毫秒數。
long currentTimeMillis = System.currentTimeMillis();
// 計算30天后的時間,用秒數表示;
long expirationSeconds = currentTimeMillis/ 1000 + 30 * 24 * 3600;
// 將秒數轉換回毫秒用於Date構造
Date expiration = new Date(expirationSeconds * 1000);
// 產生以GET方法訪問的簽名URL,在簽名URL有效期間內訪客可以直接通過瀏覽器訪問相關內容。
URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
System.out.println(url);
} catch (OSSException oe) {
System.out.println("Caught an OSSException, which means your request made it to OSS, "
+ "but was rejected with an error response for some reason.");
System.out.println("Error Message:" + oe.getErrorMessage());
System.out.println("Error Code:" + oe.getErrorCode());
System.out.println("Request ID:" + oe.getRequestId());
System.out.println("Host ID:" + oe.getHostId());
} catch (ClientException ce) {
System.out.println("Caught an ClientException, which means the client encountered "
+ "a serious internal problem while trying to communicate with OSS, "
+ "such as not being able to access the network.");
System.out.println("Error Message:" + ce.getMessage());
} finally {
if (ossClient != null) {
ossClient.shutdown();
}
}
}
}
<?php
if (is_file(__DIR__ . '/../autoload.php')) {
require_once __DIR__ . '/../autoload.php';
}
if (is_file(__DIR__ . '/../vendor/autoload.php')) {
require_once __DIR__ . '/../vendor/autoload.php';
}
use OSS\OssClient;
use OSS\Core\OssException;
use OSS\Http\RequestCore;
use OSS\Http\ResponseCore;
// 從環境變數中擷取訪問憑證。
$accessKeyId = getenv("OSS_ACCESS_KEY_ID");
$accessKeySecret = getenv("OSS_ACCESS_KEY_SECRET");
// yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
$endpoint = "yourEndpoint";
// 填寫Bucket名稱。
$bucket= "examplebucket";
// 填寫不包含Bucket名稱在內的Object完整路徑。
$object = "exampleobject.txt";
// 指定簽名URL到期時間,單位為秒,本樣本以設定簽名ULR到期時間為30天為例。您可以根據實際業務情境,設定合理的到期時間。
$timeout = 2592000;
try {
$ossClient = new OssClient($accessKeyId, $accessKeySecret, $endpoint, false);
// 產生GetObject的簽名URL。
$signedUrl = $ossClient->signUrl($bucket, $object, $timeout);
} catch (OssException $e) {
printf(__FUNCTION__ . ": FAILED\n");
printf($e->getMessage() . "\n");
return;
}
print(__FUNCTION__ . ": signedUrl: " . $signedUrl . "\n");
// 您可以使用代碼來訪問簽名URL,也可以輸入到瀏覽器地址欄中進行訪問。
$request = new RequestCore($signedUrl);
// 產生的簽名URL預設以GET方式訪問。
$request->set_method('GET');
$request->add_header('Content-Type', '');
$request->send_request();
$res = new ResponseCore($request->get_response_header(), $request->get_response_body(), $request->get_response_code());
if ($res->isOK()) {
print(__FUNCTION__ . ": OK" . "\n");
} else {
print(__FUNCTION__ . ": FAILED" . "\n");
};
# -*- coding: utf-8 -*-
import oss2
from oss2.credentials import EnvironmentVariableCredentialsProvider
import requests
# 從環境變數中擷取訪問憑證。
auth = oss2.ProviderAuth(EnvironmentVariableCredentialsProvider())
# yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
# 填寫Bucket名稱,例如examplebucket。
bucket = oss2.Bucket(auth, 'yourEndpoint', 'examplebucket')
# 填寫Object完整路徑,例如exampledir/exampleobject.txt。Object完整路徑中不能包含Bucket名稱。
object_name = 'exampledir/exampleobject.txt'
# 指定簽名URL到期時間,單位為秒,本樣本以設定簽名ULR到期時間為30天為例。您可以根據實際業務情境,設定合理的到期時間。
# 產生簽名URL時,OSS預設會對Object完整路徑中的正斜線(/)進行轉義,從而導致產生的簽名URL無法直接使用。
# 設定slash_safe為True,OSS不會對Object完整路徑中的正斜線(/)進行轉義,此時產生的簽名URL可以直接使用。
url = bucket.sign_url('GET', object_name, 2592000, slash_safe=True)
print('簽名url的地址為:', url)
# 使用簽名URL將Object下載到本地。
# 填寫本地檔案的完整路徑,例如D:\\localpath\\examplefile.txt。
# 如果未指定本地路徑只設定了本地檔案名稱(例如examplefile.txt),則下載後的檔案預設儲存到樣本程式所屬專案對應本地路徑中。
result = bucket.get_object_with_url_to_file(url, 'D:\\localpath\\examplefile.txt')
print(result.read())
package main
import (
"fmt"
"os"
"github.com/aliyun/aliyun-oss-go-sdk/oss"
)
func main() {
/// 從環境變數中擷取訪問憑證。
provider, err := oss.NewEnvironmentVariableCredentialsProvider()
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 建立OSSClient執行個體。
// yourEndpoint填寫Bucket對應的Endpoint,以華東1(杭州)為例,填寫為https://oss-cn-hangzhou.aliyuncs.com。其他Region請按實際情況填寫。
client, err := oss.New("yourEndpoint", "", "", oss.SetCredentialsProvider(&provider))
if err != nil {
fmt.Println("Error:", err)
os.Exit(-1)
}
// 填寫Bucket名稱,例如examplebucket。
bucketName := "examplebucket"
// 填寫檔案完整路徑,例如exampledir/exampleobject.txt。檔案完整路徑中不能包含Bucket名稱。
objectName := "exampledir/exampleobject.txt"
// 下載OSS檔案到本地檔案,並儲存到指定的本地路徑中。如果指定的本地檔案存在會覆蓋,不存在則建立。
// 如果未指定本地路徑,則下載後的檔案預設儲存到樣本程式所屬專案對應本地路徑中。
localDownloadedFilename := "D:\\localpath\\examplefile.txt"
// 擷取儲存空間。
bucket, err := client.Bucket(bucketName)
if err != nil {
HandleError(err)
}
// 指定簽名URL到期時間,單位為秒,本樣本以設定簽名ULR到期時間為30天為例。您可以根據實際業務情境,設定合理的到期時間。
signedURL, err := bucket.SignURL(objectName, oss.HTTPGet, 2592000)
if err != nil {
HandleError(err)
}
body, err := bucket.GetObjectWithURL(signedURL)
if err != nil {
HandleError(err)
}
// 讀取內容。
data, err := ioutil.ReadAll(body)
body.Close()
data = data // use data。
// 使用簽名URL將OSS檔案下載到本地檔案。
err = bucket.GetObjectToFileWithURL(signedURL, localDownloadedFilename)
if err != nil {
HandleError(err)
}
}
using Aliyun.OSS;
using Aliyun.OSS.Common;
// 填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。
var endpoint = "https://oss-cn-hangzhou.aliyuncs.com";
// 從環境變數中擷取訪問憑證。
var accessKeyId = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_ID");
var accessKeySecret = Environment.GetEnvironmentVariable("OSS_ACCESS_KEY_SECRET");
// 填寫Bucket名稱,例如examplebucket。
var bucketName = "examplebucket";
// 填寫Object完整路徑,完整路徑中不包含Bucket名稱,例如exampledir/exampleobject.txt。
var objectName = "exampledir/exampleobject.txt";
// 填寫Object下載到本地檔案的完整路徑。例如D:\\localpath\\examplefile.txt。如果指定的本地檔案存在會覆蓋,不存在則建立。
var downloadFilename = "D:\\localpath\\examplefile.txt";
// 建立OSSClient執行個體。
var client = new OssClient(endpoint, accessKeyId, accessKeySecret);
try
{
var metadata = client.GetObjectMetadata(bucketName, objectName);
var etag = metadata.ETag;
// 產生簽名URL。
var req = new GeneratePresignedUriRequest(bucketName, objectName, SignHttpMethod.Get)
{
// 指定簽名URL到期時間,單位為小時,本樣本以設定簽名ULR到期時間為30天為例。您可以根據實際業務情境,設定合理的到期時間。
Expiration = DateTime.Now.AddHours(720),
};
var uri = client.GeneratePresignedUri(req);
// 使用簽名URL下載檔案。
OssObject ossObject = client.GetObject(uri);
using (var file = File.Open(downloadFilename, FileMode.OpenOrCreate))
{
using (Stream stream = ossObject.Content)
{
int length;
int bufLength = 4 * 1024;
var buf = new byte[bufLength];
do
{
length = requestStream.Read(buf, 0, bufLength);
fs.Write(buf, 0, length);
} while (length != 0);
}
}
Console.WriteLine("Get object by signatrue succeeded. {0} ", uri.ToString());
}
catch (OssException ex)
{
Console.WriteLine("Failed with error code: {0}; Error info: {1}. \nRequestID:{2}\tHostID:{3}",
ex.ErrorCode, ex.Message, ex.RequestId, ex.HostId);
}
catch (Exception ex)
{
Console.WriteLine("Failed with error info: {0}", ex.Message);
}
#include <alibabacloud/oss/OssClient.h>
using namespace AlibabaCloud::OSS;
int main(void)
{
/* 初始化OSS帳號資訊。*/
/* yourEndpoint填寫Bucket所在地區對應的Endpoint。以華東1(杭州)為例,Endpoint填寫為https://oss-cn-hangzhou.aliyuncs.com。*/
std::string Endpoint = "yourEndpoint";
/* 填寫Bucket名稱,例如examplebucket。*/
std::string BucketName = "examplebucket";
/* 填寫Object完整路徑,完整路徑中不能包含Bucket名稱,例如exampledir/exampleobject.txt。*/
std::string GetobjectUrlName = "exampledir/exampleobject.txt";
/* 初始化網路等資源。*/
InitializeSdk();
ClientConfiguration conf;
/* 從環境變數中擷取訪問憑證。*/
auto credentialsProvider = std::make_shared<EnvironmentVariableCredentialsProvider>();
OssClient client(Endpoint, credentialsProvider, conf);
/* 指定簽名URL到期時間,單位為秒,本樣本以設定簽名ULR到期時間為30天為例。您可以根據實際業務情境,設定合理的到期時間。*/
std::time_t t = std::time(nullptr) + 2592000;
/* 產生簽名URL。*/
auto genOutcome = client.GeneratePresignedUrl(BucketName, GetobjectUrlName, t, Http::Get);
if (genOutcome.isSuccess()) {
std::cout << "GeneratePresignedUrl success, Gen url:" << genOutcome.result().c_str() << std::endl;
}
else {
/* 異常處理。*/
std::cout << "GeneratePresignedUrl fail" <<
",code:" << genOutcome.error().Code() <<
",message:" << genOutcome.error().Message() <<
",requestId:" << genOutcome.error().RequestId() << std::endl;
ShutdownSdk();
return -1;
}
/* 使用簽名URL下載檔案。*/
auto outcome = client.GetObjectByUrl(genOutcome.result());
if (!outcome.isSuccess()) {
/* 異常處理。*/
std::cout << "GetObjectByUrl fail" <<
",code:" << outcome.error().Code() <<
",message:" << outcome.error().Message() <<
",requestId:" << outcome.error().RequestId() << std::endl;
ShutdownSdk();
return -1;
}
/* 釋放網路等資源。*/
ShutdownSdk();
return 0;
}
步驟二:設定防盜鏈
OSS支援對Bucket設定防盜鏈,通過設定白名單避免OSS資源被盜用。
假設為儲存空間examplebucket設定防盜鏈,限制僅允許Referer為http://www.example.com的IP地址訪問,具體操作步驟如下:
登入OSS管理主控台。
單擊Bucket列表,然後單擊examplebucket。
在左側導覽列,選擇資料安全 > 防盜鏈。
在防盜鏈頁面,開啟防盜鏈開關。
在白名單Referer輸入框中,填寫https://192.168.0.0 。
在空Referer地區,選擇不允許空Referer,即只有在HTTP或HTTPS要求標頭中包含Referer欄位的請求才能訪問OSS資源。
在截斷QueryString地區,選擇是否允許截斷QueryString。
允許:OSS匹配該Referer時預設截斷QueryString。例如Referer設定為
http://www.example.com/?action=nop
,OSS匹配該Referer時預設截斷QueryString,即使用http://www.example.com/
進行匹配。不允許:OSS匹配該Referer時不截斷QueryString。例如Referer設定為
http://www.example.com/?action=nop
,OSS會使用http://www.example.com/?action=nop
進行匹配。關於QueryString的解析規則,請參見QueryString解析規則。
單擊儲存。
關於防盜鏈的更多資訊,請參見防盜鏈。