Anda dapat memanggil operasi PostObject untuk mengunggah file langsung dari klien web ke Object Storage Service (OSS). Anda dapat menambahkan informasi tanda tangan yang dihasilkan di server aplikasi untuk mengamankan pengunggahan ini dan mengonfigurasi kebijakan pengunggahan yang sesuai untuk menerapkan pembatasan yang memenuhi persyaratan bisnis Anda.
Ikhtisar Solusi
Gambar berikut menunjukkan cara menghasilkan tanda tangan pada server aplikasi dan menggunakan tanda tangan tersebut untuk mengunggah file langsung dari klien web ke OSS.
Untuk mendapatkan informasi tanda tangan dari server aplikasi dan mengunggah data ke OSS, ikuti langkah-langkah berikut:
Dalam proses ini, kredensial akses sementara digunakan. Ini mencegah pasangan AccessKey dari server aplikasi bocor dan memastikan keamanan pengunggahan file.
Siapkan Sumber Daya OSS: Buat bucket untuk menyimpan data yang diunggah dan konfigurasikan aturan berbagi sumber daya lintas domain (CORS) untuk bucket tersebut agar permintaan lintas domain dari klien web diizinkan.
Konfigurasikan Server Aplikasi: Pada langkah ini, panggil operasi yang sesuai dari Security Token Service (STS) untuk mendapatkan sepasang kredensial akses sementara. Kemudian, gunakan kredensial akses sementara dan kebijakan pengunggahan yang telah ditentukan sebelumnya di server aplikasi untuk menghasilkan tanda tangan dan memberi otorisasi kepada pengguna untuk mengunggah file dalam periode waktu tertentu. Kebijakan pengunggahan mencakup informasi seperti nama bucket, jalur direktori, dan waktu kedaluwarsa.
Konfigurasikan Klien Web: Buat formulir HTML dan gunakan formulir tersebut untuk mengirimkan tanda tangan dan mengunggah objek ke OSS.
Proyek Demo
Proyek Java: server-signed-direct-upload-java.zip
Proyek Python: server-signed-direct-upload-python.zip
Proyek Node.js: server-signed-direct-upload-nodejs.zip
Proyek Go: server-signed-direct-upload-go.zip
Proyek PHP: server-signed-direct-upload-php.zip
Prosedur
Langkah 1: Siapkan Sumber Daya OSS
1. Buat Bucket
Buat bucket OSS untuk menyimpan data yang diunggah oleh aplikasi web dari browser.
Masuk ke Konsol OSS.
Di panel navigasi sisi kiri, klik Buckets. Di halaman Buckets, klik Create Bucket.
Di panel Create Bucket, konfigurasikan parameter yang dijelaskan dalam parameter berikut.
Parameter
Nilai Contoh
Bucket Name
web-direct-upload
Region
Cina (Hangzhou)
Klik Create.
2. Konfigurasikan Aturan CORS
Konfigurasikan aturan CORS untuk bucket yang Anda buat.
Di halaman Buckets, klik nama bucket.
Di pohon navigasi sisi kiri halaman yang muncul, pilih Content Security > CORS. Di halaman CORS, klik Create Rule.
Di panel Create Rule, konfigurasikan parameter yang dijelaskan dalam tabel berikut.
Parameter
Nilai Contoh
Source
*
Allowed Methods
POST, PUT, dan GET
Allowed Headers
*
Klik OK.
Langkah 2: Konfigurasikan Server Aplikasi
Jika Anda sudah memiliki server aplikasi yang tersedia dalam penyebaran Anda, Anda dapat melewati langkah-langkah persiapan dan mulai langsung dengan konfigurasi izin pengguna.
Persiapan: Buat Instance ECS sebagai server aplikasi
Operasi 1: Buat Instance ECS
Di tab Custom Launch pada halaman pembelian instance di konsol Elastic Compute Service (ECS), buat atau pilih sumber daya dasar yang diperlukan oleh instance ECS.
Pilih Wilayah dan Metode Penagihan
Pilih metode penagihan berdasarkan kebutuhan bisnis Anda. Dalam contoh ini, metode penagihan Pay-as-you-go dipilih.
Pilih wilayah berdasarkan kebutuhan latensi jaringan Anda. Wilayah yang lebih dekat dengan pengguna umumnya menawarkan latensi lebih rendah dan akses lebih cepat. Dalam contoh ini, wilayah Cina (Hangzhou) dipilih.

Buat Virtual Private Cloud (VPC) dan vSwitch
Saat membuat VPC, pilih wilayah tempat Anda membuat instance ECS dan rencanakan blok CIDR berdasarkan kebutuhan bisnis Anda. Dalam contoh ini, VPC dan vSwitch dibuat di wilayah Cina (Hangzhou). Setelah membuat VPC, kembali ke tab Custom Launch halaman pembelian instance di konsol ECS, segarkan daftar drop-down VPC dan vSwitch, lalu pilih VPC dan vSwitch yang Anda buat.
CatatanAnda juga dapat membuat vSwitch selama pembuatan VPC.



Pilih Tipe Instance dan Gambar
Pilih tipe instance dan gambar. Gambar yang dipilih menentukan sistem operasi dan versinya. Contoh ini menggunakan tipe instance hemat biaya
ecs.e-c1m1.largedan gambar publikAlibaba Cloud Linux 3.2104 LTS 64-bit.
Konfigurasikan Penyimpanan
Konfigurasikan disk sistem dan disk data untuk instance ECS berdasarkan kebutuhan bisnis Anda. Karena proyek demo ini menerapkan aplikasi web ringan, disk sistem saja sudah cukup, dan tidak ada disk data yang dikonfigurasi.

Tetapkan Alamat IP Publik
Untuk memberikan konektivitas Internet ke instance ECS, pilih Tetapkan Alamat IPv4 Publik untuk menetapkan alamat IP publik ke instance. Sebagai alternatif, Anda dapat mengaitkan alamat IP elastis (EIP) dengan instance ECS setelah Anda membuat instance. Untuk informasi lebih lanjut, lihat Asosiasikan EIP dengan Instance ECS.
CatatanJika Anda tidak menetapkan alamat IP publik atau mengaitkan EIP dengan instance ECS, Anda tidak dapat mengakses instance melalui SSH atau Remote Desktop Protocol (RDP), atau menguji layanan web yang diterapkan pada instance melalui Internet.
Setelah Anda memilih Tetapkan Alamat IPv4 Publik, tetapkan Metode Penagihan Bandwidth untuk menentukan metode penagihan untuk penggunaan jaringan. Dalam contoh ini, parameter Metode Penagihan Bandwidth diatur ke Pay-by-traffic. Dalam metode bayar berdasarkan lalu lintas, Anda dikenakan biaya berdasarkan jumlah data yang ditransfer melalui Internet. Untuk informasi lebih lanjut, lihat Bandwidth Publik.

Buat Grup Keamanan
Buat grup keamanan untuk instance ECS. Grup keamanan berfungsi sebagai firewall virtual yang mengontrol lalu lintas masuk dan keluar untuk instance ECS. Saat membuat grup keamanan, buka port berikut untuk mengizinkan akses ke instance ECS:
Buka Port/Protokol IPv4: pilih SSH (TCP:22), RDP (TCP:3389), HTTP (TCP:80), dan HTTPS (TCP:443).
CatatanPort yang dipilih untuk Open IPv4 Ports/Protocols adalah port yang perlu dibuka untuk aplikasi yang berjalan di instance ECS.
Jika SSH (TCP:22) dipilih dalam proses ini, grup keamanan secara otomatis berisi aturan yang mengizinkan lalu lintas dari 0.0.0.0/0, yang mewakili semua alamat IP. Aturan tersebut mengizinkan akses ke instance ECS dari semua alamat IP pada port yang ditentukan. Setelah Anda membuat instance, kami sarankan Anda memodifikasi aturan untuk mengizinkan akses ke instance hanya dari alamat IP tertentu. Untuk informasi lebih lanjut, lihat Modifikasi Aturan Grup Keamanan.

Buat Pasangan Kunci
Anda dapat mengikat pasangan kunci ke instance ECS dan menggunakan pasangan kunci sebagai kredensial untuk mengotentikasi identitas Anda saat masuk ke instance. Setelah membuat pasangan kunci, unduh kunci privat dari pasangan kunci untuk digunakan nanti saat Anda terhubung ke instance ECS. Setelah membuat pasangan kunci, kembali ke tab Custom Launch halaman pembelian instance, segarkan daftar drop-down Pasangan Kunci, lalu pilih pasangan kunci yang Anda buat.
rootadalah akun dengan hak istimewa tertinggi dalam sistem operasi. Jika Anda memilihrootsebagai nama pengguna masuk, risiko keamanan mungkin timbul. Kami sarankan Anda memilihecs-usersebagai nama pengguna masuk.CatatanSetelah Anda membuat pasangan kunci, file kunci privat dari pasangan kunci secara otomatis diunduh. Lihat riwayat unduhan browser Anda untuk menemukan file kunci privat dalam format
.pem.
Selesaikan Pembuatan Instance dan Lihat Instance
Setelah Anda membuat atau memilih sumber daya yang diperlukan, klik Create Order. Di pesan Sukses, klik Console untuk melihat instance ECS yang dibuat. Catat informasi berikut untuk digunakan nanti:
ID Instance: Anda dapat mencari instance ECS berdasarkan ID instance.
Wilayah dan zona: Anda dapat mencari instance ECS berdasarkan wilayah dan zona.
Alamat IP Publik: Anda dapat menggunakan alamat IP publik dari instance ECS untuk mengakses layanan web yang diterapkan pada instance.


Operasi 2: Hubungkan ke Instance ECS
Di halaman Instance di ECS console, temukan instance ECS yang Anda buat berdasarkan wilayah dan ID-nya. Lalu, klik Connect di kolom Actions.

Di kotak dialog Remote connection, klik Sign in now di bagian Workbench.

Di kotak dialog Instance Login, atur Connection Method ke Terminal Connection dan Authentication Method ke SSH Key Authentication. Lalu, masukkan atau unggah kunci privat yang diunduh saat Anda membuat pasangan kunci, dan Log On ke instance ECS sebagai
ecs-user.- Catatan
File kunci privat secara otomatis diunduh ke komputer lokal Anda saat Anda membuat pasangan kunci. Lihat riwayat unduhan browser Anda untuk menemukan file kunci privat dalam format
.pem. Jika halaman serupa dengan yang ditunjukkan dalam gambar berikut muncul, Anda telah masuk ke instance ECS.

1. Konfigurasikan Izin Pengguna
Kami sarankan Anda memberikan izin yang diperlukan kepada pengguna RAM dengan menggunakan langkah-langkah berikut, untuk mencegah kegagalan dalam mengunggah file ke OSS karena izin tidak mencukupi.
Operasi 1: Buat Pengguna RAM di Konsol RAM
Buat pengguna RAM dan dapatkan pasangan AccessKey dari pengguna RAM. Pasangan AccessKey adalah kredensial akses jangka panjang yang diperlukan untuk mengakses dan mengelola aplikasi.
Masuk ke Konsol RAM menggunakan akun Alibaba Cloud atau sebagai administrator akun.
Di panel navigasi sisi kiri, pilih Identities > Pengguna.
Di halaman Pengguna, klik Create User.
Konfigurasikan parameter Logon Name dan Display Name.
Di bagian Access Mode, pilih Using permanent AccessKey to access dan klik OK.
Anda hanya dapat memperoleh rahasia AccessKey dari pengguna RAM saat Anda membuat pengguna RAM. Anda harus menjaga kerahasiaan rahasia AccessKey untuk mencegah kebocoran kredensial.
Di halaman yang muncul, klik Copy di kolom Actions untuk menyalin pasangan AccessKey dan tempelkan ke file yang disimpan dengan aman.
Operasi 2: Berikan Izin kepada Pengguna RAM untuk Memanggil Operasi AssumeRole
Berikan izin kepada pengguna RAM untuk memanggil operasi AssumeRole. Dengan cara ini, pengguna RAM dapat memperoleh kredensial akses sementara dengan mengasumsikan peran RAM.
Di panel navigasi sisi kiri, pilih Identities > Pengguna.
Di halaman Users, temukan pengguna RAM dan klik Add Permissions di kolom Tindakan.
Di bagian Kebijakan panel Grant Permission, pilih kebijakan AliyunSTSAssumeRoleAccess.
CatatanKebijakan AliyunSTSAssumeRoleAccess mengizinkan pengguna RAM untuk memanggil operasi AssumeRole. Kebijakan ini tidak memberikan izin yang diperlukan oleh pengguna RAM untuk memperoleh kredensial akses sementara dari STS dan memulai permintaan ke OSS.
Klik Grant permissions.
Operasi 3: Buat Peran RAM di Konsol RAM
Buat peran RAM untuk akun Alibaba Cloud dan dapatkan Nama Sumber Daya Alibaba Cloud (ARN) dari peran RAM. Peran RAM diasumsikan oleh pengguna RAM nanti.
Di panel navigasi sisi kiri, pilih Identities > Peran.
Klik Create Role dan pilih Cloud Account untuk parameter Jenis Principal.
Pilih Current Account untuk Nama Principal.
Di kotak dialog yang muncul, masukkan Nama Peran dan klik OK.
Di halaman yang muncul, klik Copy untuk menyimpan ARN dari peran.
Operasi 4: Buat Kebijakan Kustom di Konsol RAM
Buat kebijakan kustom berdasarkan prinsip hak istimewa minimal untuk memberikan izin kepada peran RAM untuk mengunggah data hanya ke bucket tertentu.
Di panel navigasi sisi kiri, pilih Permissions > Kebijakan.
Di halaman Kebijakan, klik Create Policy.
Di halaman Create Policy, klik JSON. Salin skrip contoh berikut dan tempelkan ke editor kode. Ganti
<BucketName>dengan nama bucket yang Anda buat, yaituweb-direct-uploaddalam contoh ini.{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": "oss:PutObject", "Resource": "acs:oss:*:*:<BucketName>/*" } ] }Klik OK.
Di kotak dialog Create Policy, masukkan Policy Name dan klik OK.
Operasi 5: Lampirkan Kebijakan Kustom ke Peran RAM di Konsol RAM
Lampirkan kebijakan kustom ke peran RAM. Dengan cara ini, peran RAM dapat memberikan izin yang diperlukan saat peran RAM diasumsikan.
Di panel navigasi sisi kiri, pilih Identities > Peran.
Di halaman Roles, temukan peran RAM dan klik Grant Permission di kolom Tindakan.
Di panel Grant Permission, pilih Custom Policy, lalu pilih kebijakan kustom.
Klik Grant permissions.
2. Dapatkan Kredensial Akses Sementara dan Hitung Tanda Tangan di Server Aplikasi
Kami menyarankan Anda membuat variabel lingkungan untuk menyimpan informasi sensitif, seperti accessKeyId, accessKeySecret, dan roleArn, guna menghindari risiko yang terkait dengan penulisan eksplisit informasi sensitif dalam kode Anda.
Ikuti langkah-langkah berikut untuk menambahkan variabel lingkungan:
Linux
Jalankan perintah berikut di CLI untuk menambahkan konfigurasi variabel lingkungan ke file
~/.bashrc:echo "export OSS_ACCESS_KEY_ID='your-access-key-id'" >> ~/.bashrc echo "export OSS_ACCESS_KEY_SECRET='your-access-key-secret'" >> ~/.bashrc echo "export OSS_STS_ROLE_ARN='your-role-arn'" >> ~/.bashrcTerapkan perubahan dengan menjalankan perintah berikut:
source ~/.bashrcPeriksa apakah variabel lingkungan telah diterapkan dengan menjalankan perintah berikut:
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET echo $OSS_STS_ROLE_ARN
macOS
Jalankan perintah berikut di terminal untuk melihat jenis Shell default:
echo $SHELLLakukan operasi sesuai dengan jenis Shell default.
Zsh
Tambahkan konfigurasi variabel lingkungan ke file
~/.zshrcdengan menjalankan perintah berikut:echo "export OSS_ACCESS_KEY_ID='your-access-key-id'" >> ~/.zshrc echo "export OSS_ACCESS_KEY_SECRET='your-access-key-secret'" >> ~/.zshrc echo "export OSS_STS_ROLE_ARN='your-role-arn'" >> ~/.zshrcTerapkan perubahan dengan menjalankan perintah berikut:
source ~/.zshrcPeriksa apakah variabel lingkungan telah diterapkan dengan menjalankan perintah berikut:
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET echo $OSS_STS_ROLE_ARN
Bash
Tambahkan konfigurasi variabel lingkungan ke file
~/.bash_profiledengan menjalankan perintah berikut:echo "export OSS_ACCESS_KEY_ID='your-access-key-id'" >> ~/.bash_profile echo "export OSS_ACCESS_KEY_SECRET='your-access-key-secret'" >> ~/.bash_profile echo "export OSS_STS_ROLE_ARN='your-role-arn'" >> ~/.bash_profileTerapkan perubahan dengan menjalankan perintah berikut:
source ~/.bash_profilePeriksa apakah variabel lingkungan telah diterapkan dengan menjalankan perintah berikut:
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET echo $OSS_STS_ROLE_ARN
Windows
Buat variabel lingkungan dengan menjalankan perintah berikut di cmd:
setx OSS_ACCESS_KEY_ID "your-access-key-id" setx OSS_ACCESS_KEY_SECRET "your-access-key-secret" setx OSS_STS_ROLE_ARN "your-role-arn"Buka jendela cmd baru.
Periksa apakah variabel lingkungan telah diterapkan dengan menjalankan perintah berikut di jendela baru:
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET% echo %OSS_STS_ROLE_ARN%
Anda dapat merujuk pada kode contoh berikut untuk menghitung tanda tangan V4 dalam permintaan PostObject di server aplikasi. Untuk detail mengenai bidang formulir kebijakan dalam permintaan PostObject, lihat kebijakan.
Java
Tambahkan dependensi berikut ke proyek Maven:
<!-- https://mvnrepository.com/artifact/com.aliyun/credentials-java -->
<dependency>
<groupId>com.aliyun.oss</groupId>
<artifactId>aliyun-sdk-oss</artifactId>
<version>3.17.4</version>
</dependency>
<dependency>
<groupId>com.aliyun</groupId>
<artifactId>sts20150401</artifactId>
<version>1.1.6</version>
</dependency>Anda dapat merujuk pada kode contoh berikut untuk menyediakan kredensial akses sementara dan menghitung tanda tangan yang digunakan dalam permintaan PostObject:
package com.aliyun.oss.web;
import com.aliyun.sts20150401.models.AssumeRoleResponse;
import com.aliyun.sts20150401.models.AssumeRoleResponseBody;
import com.aliyun.tea.TeaException;
import com.aliyun.oss.common.utils.BinaryUtil;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.codec.binary.Base64;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.*;
@Controller
public class WebController {
// Informasi bucket OSS. Ganti nilai-nilai dengan informasi sebenarnya Anda.
String bucket = "examplebucket";
String region = "cn-hangzhou";
String host = "http://examplebucket.oss-cn-hangzhou.aliyuncs.com";
// Tentukan URL server aplikasi ke mana permintaan callback pengunggahan dikirim. URL tersebut harus menggunakan domain publik. URL ini digunakan untuk komunikasi antara server aplikasi dan OSS. Setelah Anda mengunggah objek, OSS menggunakan URL tersebut untuk mengirim informasi pengunggahan ke server aplikasi.
// Awalan nama objek yang diunggah ke OSS.
String upload_dir = "dir";
// Masa berlaku kredensial sementara. Unit: detik.
Long expire_time = 3600L;
/**
* Waktu kedaluwarsa dihitung berdasarkan periode validitas yang ditentukan. Unit: detik.
* @param seconds: periode validitas, dalam detik.
* @return: string waktu dalam standar ISO 8601. Contoh: 2014-12-01T12:00:00.000Z.
*/
public static String generateExpiration(long seconds) {
// Timestamp saat ini. Unit: detik.
long now = Instant.now().getEpochSecond();
// Timestamp untuk waktu kedaluwarsa.
long expirationTime = now + seconds;
// Konversi timestamp menjadi objek Instant dan format dalam format ISO 8601.
Instant instant = Instant.ofEpochSecond(expirationTime);
// Atur zona waktu ke UTC.
ZoneId zone = ZoneOffset.UTC;
// Konversi objek Instant menjadi objek ZonedDateTime.
ZonedDateTime zonedDateTime = instant.atZone(zone);
// Definisikan format tanggal dan waktu. Contoh: 2023-12-03T13:00:00.000Z.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
// Format tanggal dan waktu.
String formattedDate = zonedDateTime.format(formatter);
// Kembalikan hasilnya.
return formattedDate;
}
// Inisialisasi instance StsClient.
public static com.aliyun.sts20150401.Client createStsClient() throws Exception {
// Jika kode proyek bocor, pasangan AccessKey mungkin bocor dan keamanan semua sumber daya dalam akun Anda mungkin terganggu. Baris berikut hanya disediakan sebagai referensi.
// Kami sarankan Anda menggunakan token STS, yang memberikan keamanan lebih tinggi.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// Pastikan variabel lingkungan OSS_ACCESS_KEY_ID dikonfigurasi.
.setAccessKeyId(System.getenv("OSS_ACCESS_KEY_ID"))
// Pastikan variabel lingkungan OSS_ACCESS_KEY_SECRET dikonfigurasi.
.setAccessKeySecret(System.getenv("OSS_ACCESS_KEY_SECRET"));
// Tentukan titik akhir wilayah tempat bucket berada. Untuk informasi lebih lanjut, kunjungi https://api.alibabacloud.com/product/Sts.
config.endpoint = "sts.cn-hangzhou.aliyuncs.com";
return new com.aliyun.sts20150401.Client(config);
}
/**
* Dapatkan token STS.
* @return Objek AssumeRoleResponseBodyCredentials.
*/
public static AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials getCredential() throws Exception {
com.aliyun.sts20150401.Client client = WebController.createStsClient();
com.aliyun.sts20150401.models.AssumeRoleRequest assumeRoleRequest = new com.aliyun.sts20150401.models.AssumeRoleRequest()
// Pastikan variabel lingkungan OSS_STS_ROLE_ARN dikonfigurasi.
.setRoleArn(System.getenv("OSS_STS_ROLE_ARN"))
.setRoleSessionName("yourRoleSessionName");// Tentukan nama sesi kustom.
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// Tulis kode Anda sendiri untuk menampilkan respons operasi API jika diperlukan.
AssumeRoleResponse response = client.assumeRoleWithOptions(assumeRoleRequest, runtime);
// AccessKey ID, AccessKey secret, dan token STS yang diperlukan untuk operasi selanjutnya termasuk dalam credentials.
return response.body.credentials;
} catch (TeaException error) {
// Tangani pengecualian dengan hati-hati dalam skenario bisnis aktual, dan jangan abaikan pengecualian dalam proyek Anda. Dalam contoh ini, pengecualian dicetak untuk demonstrasi.
// Tampilkan pesan kesalahan.
System.out.println(error.getMessage());
// Tampilkan URL untuk pemecahan masalah.
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
// Kembalikan objek respons kesalahan default alih-alih null.
AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials defaultCredentials = new AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials();
defaultCredentials.accessKeyId = "ERROR_ACCESS_KEY_ID";
defaultCredentials.accessKeySecret = "ERROR_ACCESS_KEY_SECRET";
defaultCredentials.securityToken = "ERROR_SECURITY_TOKEN";
return defaultCredentials;
}
@GetMapping("/get_post_signature_for_oss_upload")
public ResponseEntity<Map<String, String>> getPostSignatureForOssUpload() throws Exception {
AssumeRoleResponseBody.AssumeRoleResponseBodyCredentials sts_data = getCredential();
String accesskeyid = sts_data.accessKeyId;
String accesskeysecret = sts_data.accessKeySecret;
String securitytoken = sts_data.securityToken;
// Dapatkan tanggal saat ini di header x-oss-credential. Nilainya dalam format yyyyMMdd.
ZonedDateTime today = ZonedDateTime.now().withZoneSameInstant(java.time.ZoneOffset.UTC);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
String date = today.format(formatter);
// Dapatkan header x-oss-date.
ZonedDateTime now = ZonedDateTime.now().withZoneSameInstant(java.time.ZoneOffset.UTC);
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("yyyyMMdd'T'HHmmss'Z'");
String x_oss_date = now.format(formatter2);
// Langkah 1: Buat kebijakan.
String x_oss_credential = accesskeyid + "/" + date + "/" + region + "/oss/aliyun_v4_request";
ObjectMapper mapper = new ObjectMapper();
Map<String, Object> policy = new HashMap<>();
policy.put("expiration", generateExpiration(expire_time));
List<Object> conditions = new ArrayList<>();
Map<String, String> bucketCondition = new HashMap<>();
bucketCondition.put("bucket", bucket);
conditions.add(bucketCondition);
Map<String, String> securityTokenCondition = new HashMap<>();
securityTokenCondition.put("x-oss-security-token", securitytoken);
conditions.add(securityTokenCondition);
Map<String, String> signatureVersionCondition = new HashMap<>();
signatureVersionCondition.put("x-oss-signature-version", "OSS4-HMAC-SHA256");
conditions.add(signatureVersionCondition);
Map<String, String> credentialCondition = new HashMap<>();
credentialCondition.put("x-oss-credential", x_oss_credential); // Ganti nilainya dengan ID AccessKey Anda.
conditions.add(credentialCondition);
Map<String, String> dateCondition = new HashMap<>();
dateCondition.put("x-oss-date", x_oss_date);
conditions.add(dateCondition);
conditions.add(Arrays.asList("content-length-range", 1, 10240000));
conditions.add(Arrays.asList("eq", "$success_action_status", "200"));
conditions.add(Arrays.asList("starts-with", "$key", upload_dir));
policy.put("conditions", conditions);
String jsonPolicy = mapper.writeValueAsString(policy);
// Langkah 2: Buat string untuk ditandatangani.
String stringToSign = new String(Base64.encodeBase64(jsonPolicy.getBytes()));
// System.out.println("stringToSign: " + stringToSign);
// Langkah 3: Hitung kunci penandatanganan.
byte[] dateKey = hmacsha256(("aliyun_v4" + accesskeysecret).getBytes(), date);
byte[] dateRegionKey = hmacsha256(dateKey, region);
byte[] dateRegionServiceKey = hmacsha256(dateRegionKey, "oss");
byte[] signingKey = hmacsha256(dateRegionServiceKey, "aliyun_v4_request");
// System.out.println("signingKey: " + BinaryUtil.toBase64String(signingKey));
// Langkah 4: Hitung tanda tangan.
byte[] result = hmacsha256(signingKey, stringToSign);
String signature = BinaryUtil.toHex(result);
// System.out.println("signature:" + signature);
Map<String, String> response = new HashMap<>();
// Tambahkan data ke objek Map.
response.put("version", "OSS4-HMAC-SHA256");
response.put("policy", stringToSign);
response.put("x_oss_credential", x_oss_credential);
response.put("x_oss_date", x_oss_date);
response.put("signature", signature);
response.put("security_token", securitytoken);
response.put("dir", upload_dir);
response.put("host", host);
// Kembalikan objek ResponseEntity yang mencakup kode status 200 OK ke klien web. Kemudian, klien dapat melakukan operasi PostObject.
return ResponseEntity.ok(response);
}
public static byte[] hmacsha256(byte[] key, String data) {
try {
// Inisialisasi SecretKeySpec, atur algoritma ke HMAC-SHA256, dan gunakan kunci yang disediakan.
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256");
// Dapatkan instance Mac dan gunakan metode getInstance untuk mengatur algoritma ke HMAC-SHA256.
Mac mac = Mac.getInstance("HmacSHA256");
// Gunakan kunci untuk menginisialisasi instance Mac.
mac.init(secretKeySpec);
// Hitung nilai HMAC. Gunakan metode doFinal untuk menerima data yang akan dihitung dan kembalikan hasil perhitungan sebagai array.
byte[] hmacBytes = mac.doFinal(data.getBytes());
return hmacBytes;
} catch (Exception e) {
throw new RuntimeException("Gagal menghitung HMAC-SHA256", e);
}
}
}Python
Jalankan perintah berikut untuk menginstal dependensi:
pip install flask
pip install alibabacloud_tea_openapi alibabacloud_sts20150401 alibabacloud_credentialsAnda dapat merujuk pada kode contoh berikut untuk menyediakan kredensial akses sementara dan membuat kebijakan pengunggahan guna menghitung tanda tangan yang digunakan dalam permintaan PostObject:
from flask import Flask, render_template, jsonify
from alibabacloud_tea_openapi.models import Config
from alibabacloud_sts20150401.client import Client as Sts20150401Client
from alibabacloud_sts20150401 import models as sts_20150401_models
from alibabacloud_credentials.client import Client as CredentialClient
import os
import json
import base64
import hmac
import datetime
import time
import hashlib
app = Flask(__name__)
# Konfigurasikan variabel lingkungan OSS_ACCESS_KEY_ID, OSS_ACCESS_KEY_SECRET, dan OSS_STS_ROLE_ARN.
access_key_id = os.environ.get('OSS_ACCESS_KEY_ID')
access_key_secret = os.environ.get('OSS_ACCESS_KEY_SECRET')
role_arn_for_oss_upload = os.environ.get('OSS_STS_ROLE_ARN')
# Tentukan nama sesi.
role_session_name = 'yourRoleSessionName'
# Ganti nilai-nilai dengan informasi sebenarnya Anda.
bucket = 'examplebucket'
region_id = 'cn-hangzhou'
host = 'http://examplebucket.oss-cn-hangzhou.aliyuncs.com'
# Masa berlaku kredensial akses sementara. Unit: detik.
expire_time = 3600
# Tentukan awalan dalam nama objek yang ingin Anda unggah ke OSS.
upload_dir = 'dir'
def hmacsha256(key, data):
"""
Fungsi ini menghitung nilai HMAC-SHA256.
:param key: Kunci yang digunakan untuk menghitung nilai hash. Kunci tersebut bertipe byte.
:param data: Data yang nilai hash-nya ingin Anda hitung. Data tersebut bertipe string.
:return: Nilai HMAC-SHA256 yang dihitung. Nilai tersebut bertipe byte.
"""
try:
mac = hmac.new(key, data.encode(), hashlib.sha256)
hmacBytes = mac.digest()
return hmacBytes
except Exception as e:
raise RuntimeError(f"Gagal menghitung HMAC-SHA256 karena {e}")
@app.route("/")
def hello_world():
return render_template('index.html')
@app.route('/get_post_signature_for_oss_upload', methods=['GET'])
def generate_upload_params():
# Inisialisasi konfigurasi.
config = Config(
region_id=region_id,
access_key_id=access_key_id,
access_key_secret=access_key_secret
)
# Buat klien STS dan dapatkan kredensial akses sementara.
sts_client = Sts20150401Client(config=config)
assume_role_request = sts_20150401_models.AssumeRoleRequest(
role_arn=role_arn_for_oss_upload,
role_session_name=role_session_name
)
response = sts_client.assume_role(assume_role_request)
token_data = response.body.credentials.to_map()
# Gunakan kredensial akses sementara yang dikembalikan oleh STS.
temp_access_key_id = token_data['AccessKeyId']
temp_access_key_secret = token_data['AccessKeySecret']
security_token = token_data['SecurityToken']
now = int(time.time())
# Konversi timestamp menjadi objek datetime.
dt_obj = datetime.datetime.utcfromtimestamp(now)
# Atur waktu kedaluwarsa menjadi 3 jam setelah waktu saat ini.
dt_obj_plus_3h = dt_obj + datetime.timedelta(hours=3)
# Waktu permintaan.
dt_obj_1 = dt_obj.strftime('%Y%m%dT%H%M%S') + 'Z'
# Tanggal permintaan.
dt_obj_2 = dt_obj.strftime('%Y%m%d')
# Waktu kedaluwarsa permintaan.
expiration_time = dt_obj_plus_3h.strftime('%Y-%m-%dT%H:%M:%S.000Z')
# Buat kebijakan dan hasilkan tanda tangan.
policy = {
"expiration": expiration_time,
"conditions": [
["eq", "$success_action_status", "200"],
{"x-oss-signature-version": "OSS4-HMAC-SHA256"},
{"x-oss-credential": f"{temp_access_key_id}/{dt_obj_2}/cn-hangzhou/oss/aliyun_v4_request"},
{"x-oss-security-token": security_token},
{"x-oss-date": dt_obj_1},
]
}
print(dt_obj_1)
policy_str = json.dumps(policy).strip()
# Langkah 2: Buat string untuk ditandatangani.
stringToSign = base64.b64encode(policy_str.encode()).decode()
# Langkah 3: Hitung kunci penandatanganan.
dateKey = hmacsha256(("aliyun_v4" + temp_access_key_secret).encode(), dt_obj_2)
dateRegionKey = hmacsha256(dateKey, "cn-hangzhou")
dateRegionServiceKey = hmacsha256(dateRegionKey, "oss")
signingKey = hmacsha256(dateRegionServiceKey, "aliyun_v4_request")
# Langkah 4: Hitung tanda tangan.
result = hmacsha256(signingKey, stringToSign)
signature = result.hex()
# Tentukan data respons.
response_data = {
'policy': stringToSign, # Bidang formulir.
'x_oss_signature_version': "OSS4-HMAC-SHA256", # Versi tanda tangan dan algoritma yang digunakan untuk menghitung tanda tangan. Atur nilainya ke OSS4-HMAC-SHA256.
'x_oss_credential': f"{temp_access_key_id}/{dt_obj_2}/cn-hangzhou/oss/aliyun_v4_request", # Parameter yang digunakan untuk menentukan informasi tentang kunci turunan.
'x_oss_date': dt_obj_1, # Waktu permintaan.
'signature': signature, # Deskripsi tanda tangan.
'host': host,
'dir': upload_dir,
'security_token': security_token # Token STS.
}
return jsonify(response_data)
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8000) # Mendengarkan alamat publik seperti 0.0.0.0 memerlukan implementasi mekanisme otentikasi yang sesuai di sisi server.Node.js
Jalankan perintah berikut untuk menginstal dependensi:
npm install ali-oss
npm install @alicloud/credentials
npm install expressAnda dapat merujuk pada kode contoh berikut untuk menyediakan kredensial akses sementara dan membuat kebijakan pengunggahan guna menghitung tanda tangan yang digunakan dalam permintaan PostObject:
const express = require('express');
const OSS = require('ali-oss');
const { STS } = require('ali-oss');
const { getCredential } = require('ali-oss/lib/common/signUtils');
const { getStandardRegion } = require('ali-oss/lib/common/utils/getStandardRegion');
const { policy2Str } = require('ali-oss/lib/common/utils/policy2Str');
const app = express();
const PORT = process.env.PORT || 8000; // Tentukan nomor port.
// Tentukan direktori tempat file statis disimpan.
app.use(express.static('templates'));
const GenerateSignature = async () => {
// Inisialisasi klien STS.
let sts = new STS({
accessKeyId: process.env.OSS_ACCESS_KEY_ID, //Dapatkan ID AccessKey pengguna RAM dari variabel lingkungan.
accessKeySecret: process.env.OSS_ACCESS_KEY_SECRET // Dapatkan rahasia AccessKey pengguna RAM dari variabel lingkungan.
});
// Panggil operasi assumeRole untuk mendapatkan kredensial akses sementara dari STS.
const result = await sts.assumeRole(process.env.OSS_STS_ROLE_ARN, '', '3600', 'yourRoleSessionName'); // Dapatkan Nama Sumber Daya Alibaba Cloud (ARN) dari peran RAM dari variabel lingkungan, atur periode validitas kredensial akses sementara ke 3600 detik, dan atur nama sesi peran ke yourRoleSessionName.
// Dapatkan nilai AccessKeyId, AccessKeySecret, dan SecurityToken.
const accessKeyId = result.credentials.AccessKeyId;
const accessKeySecret = result.credentials.AccessKeySecret;
const securityToken = result.credentials.SecurityToken;
// Inisialisasi instans klien OSS.
const client = new OSS({
bucket: 'examplebucket', // Ganti examplebucket dengan nama bucket yang sebenarnya.
region: 'cn-hangzhou', // Ganti cn-hangzhou dengan ID wilayah tempat bucket berada.
accessKeyId,
accessKeySecret,
stsToken: securityToken,
refreshSTSTokenInterval: 0,
refreshSTSToken: async () => {
const { accessKeyId, accessKeySecret, securityToken } = await client.getCredential();
return { accessKeyId, accessKeySecret, stsToken: securityToken };
},
});
// Buat Map untuk menyimpan bidang formulir.
const formData = new Map();
// Atur waktu kedaluwarsa tanda tangan menjadi 10 menit setelah waktu saat ini.
const date = new Date();
const expirationDate = new Date(date);
expirationDate.setMinutes(date.getMinutes() + 10);
// Format tanggal sebagai string waktu UTC yang sesuai dengan standar ISO 8601.
function padTo2Digits(num) {
return num.toString().padStart(2, '0');
}
function formatDateToUTC(date) {
return (
date.getUTCFullYear() +
padTo2Digits(date.getUTCMonth() + 1) +
padTo2Digits(date.getUTCDate()) +
'T' +
padTo2Digits(date.getUTCHours()) +
padTo2Digits(date.getUTCMinutes()) +
padTo2Digits(date.getUTCSeconds()) +
'Z'
);
}
const formattedDate = formatDateToUTC(expirationDate);
// Buat x-oss-credential dan tentukan data formulir.
const credential = getCredential(formattedDate.split('T')[0], getStandardRegion(client.options.region), client.options.accessKeyId);
formData.set('x_oss_date', formattedDate);
formData.set('x_oss_credential', credential);
formData.set('x_oss_signature_version', 'OSS4-HMAC-SHA256');
// Buat kebijakan.
// Contoh kebijakan berikut hanya berisi bidang yang wajib diisi.
const policy = {
expiration: expirationDate.toISOString(),
conditions: [
{ 'bucket': 'examplebucket'},
{ 'x-oss-credential': credential },
{ 'x-oss-signature-version': 'OSS4-HMAC-SHA256' },
{ 'x-oss-date': formattedDate },
],
};
// Jika token STS ada, tambahkan ke kebijakan dan data formulir.
if (client.options.stsToken) {
policy.conditions.push({ 'x-oss-security-token': client.options.stsToken });
formData.set('security_token', client.options.stsToken);
}
// Hasilkan tanda tangan dan tentukan data formulir.
const signature = client.signPostObjectPolicyV4(policy, date);
formData.set('policy', Buffer.from(policy2Str(policy), 'utf8').toString('base64'));
formData.set('signature', signature);
// Kembalikan data formulir.
return {
host: `http://${client.options.bucket}.oss-${client.options.region}.aliyuncs.com`,
policy: Buffer.from(policy2Str(policy), 'utf8').toString('base64'),
x_oss_signature_version: 'OSS4-HMAC-SHA256',
x_oss_credential: credential,
x_oss_date: formattedDate,
signature: signature,
dir: 'user-dir', // Tentukan awalan dalam nama objek yang ingin Anda unggah ke OSS.
security_token: client.options.stsToken
};
};
app.get('/get_post_signature_for_oss_upload', async (req, res) => {
try {
const result = await GenerateSignature();
res.json(result); // Kembalikan data tanda tangan yang dihasilkan.
} catch (error) {
console.error('Error generating signature:', error);
res.status(500).send('Error generating signature');
}
});
app.listen(PORT, () => {
console.log(`Server is running on http://127.0.0.1:${PORT}`); // Mendengarkan alamat publik seperti 0.0.0.0 memerlukan implementasi mekanisme autentikasi yang sesuai di sisi server.
});Go
Jalankan perintah berikut untuk menginstal dependensi:
go get -u github.com/aliyun/credentials-go
go mod tidyAnda dapat merujuk pada kode contoh berikut untuk menyediakan kredensial akses sementara dan membuat kebijakan pengunggahan guna menghitung tanda tangan yang digunakan dalam permintaan PostObject:
package main
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/hex"
"encoding/json"
"fmt"
"io"
"hash"
"log"
"net/http"
"os"
"time"
"github.com/aliyun/credentials-go/credentials"
)
// Definisikan variabel global.
var (
region string
bucketName string
product = "oss"
)
// Gunakan struktur PolicyToken untuk menyimpan data formulir yang dihasilkan.
type PolicyToken struct {
Policy string `json:"policy"`
SecurityToken string `json:"security_token"`
SignatureVersion string `json:"x_oss_signature_version"`
Credential string `json:"x_oss_credential"`
Date string `json:"x_oss_date"`
Signature string `json:"signature"`
Host string `json:"host"`
Dir string `json:"dir"`
}
func main() {
// Tentukan string IP dan port default.
strIPPort := ":8000"
if len(os.Args) == 3 {
strIPPort = fmt.Sprintf("%s:%s", os.Args[1], os.Args[2])
} else if len(os.Args) != 1 {
fmt.Println("Usage : go run test1.go ")
fmt.Println("Usage : go run test1.go ip port ")
fmt.Println("")
os.Exit(0)
}
// Tampilkan alamat IP dan port server.
fmt.Printf("server is running on %s \n", strIPPort)
// Daftarkan fungsi yang memproses permintaan jalur root.
http.HandleFunc("/", handlerRequest)
// Daftarkan fungsi yang memproses permintaan yang dimulai untuk mendapatkan tanda tangan.
http.HandleFunc("/get_post_signature_for_oss_upload", handleGetPostSignature)
// Mulai server HTTP.
err := http.ListenAndServe(strIPPort, nil)
if err != nil {
strError := fmt.Sprintf("http.ListenAndServe failed : %s \n", err.Error())
panic(strError)
}
}
// Gunakan fungsi handlerRequest untuk memproses permintaan ke jalur root.
func handlerRequest(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
http.ServeFile(w, r, "templates/index.html")
return
}
http.NotFound(w, r)
}
// Gunakan fungsi handleGetPostSignature untuk memproses permintaan yang dimulai untuk mendapatkan tanda tangan.
func handleGetPostSignature(w http.ResponseWriter, r *http.Request) {
if r.Method == "GET" {
response := getPolicyToken()
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*") // Izinkan permintaan lintas domain.
w.Write([]byte(response))
return
}
http.NotFound(w, r)
}
// Gunakan fungsi getPolicyToken untuk menghasilkan tanda tangan dan kredensial akses yang diperlukan untuk mengunggah objek.
func getPolicyToken() string {
// Tentukan wilayah tempat bucket berada.
region = "cn-hangzhou"
// Tentukan bucket.
bucketName = "examplebucket"
// Tentukan URL ke mana data diunggah.
host := fmt.Sprintf("https://%s.oss-%s.aliyuncs.com", bucketName, region)
// Tentukan direktori ke mana Anda ingin mengunggah objek.
dir := "user-dir"
config := new(credentials.Config).
SetType("ram_role_arn").
SetAccessKeyId(os.Getenv("OSS_ACCESS_KEY_ID")).
SetAccessKeySecret(os.Getenv("OSS_ACCESS_KEY_SECRET")).
SetRoleArn("OSS_STS_ROLE_ARN").
SetRoleSessionName("Role_Session_Name").
SetPolicy("").
SetRoleSessionExpiration(3600)
// Buat penyedia kredensial berdasarkan konfigurasi.
provider, err := credentials.NewCredential(config)
if err != nil {
log.Fatalf("NewCredential fail, err:%v", err)
}
// Dapatkan kredensial akses dari penyedia kredensial.
cred, err := provider.GetCredential()
if err != nil {
log.Fatalf("GetCredential fail, err:%v", err)
}
// Buat kebijakan.
utcTime := time.Now().UTC()
date := utcTime.Format("20060102")
expiration := utcTime.Add(1 * time.Hour)
policyMap := map[string]any{
"expiration": expiration.Format("2006-01-02T15:04:05.000Z"),
"conditions": []any{
map[string]string{"bucket": bucketName},
map[string]string{"x-oss-signature-version": "OSS4-HMAC-SHA256"},
map[string]string{"x-oss-credential": fmt.Sprintf("%v/%v/%v/%v/aliyun_v4_request", *cred.AccessKeyId, date, region, product)},
map[string]string{"x-oss-security-token": *cred.SecurityToken},
map[string]string{"x-oss-date": utcTime.Format("20060102T150405Z")},
},
}
// Konversi format kebijakan ke JSON.
policy, err := json.Marshal(policyMap)
if err != nil {
log.Fatalf("json.Marshal fail, err:%v", err)
}
// Buat string untuk ditandatangani.
stringToSign := base64.StdEncoding.EncodeToString([]byte(policy))
hmacHash := func() hash.Hash { return sha256.New() }
// Buat kunci penandatanganan.
signingKey := "aliyun_v4" + *cred.AccessKeySecret
h1 := hmac.New(hmacHash, []byte(signingKey))
io.WriteString(h1, date)
h1Key := h1.Sum(nil)
h2 := hmac.New(hmacHash, h1Key)
io.WriteString(h2, region)
h2Key := h2.Sum(nil)
h3 := hmac.New(hmacHash, h2Key)
io.WriteString(h3, product)
h3Key := h3.Sum(nil)
h4 := hmac.New(hmacHash, h3Key)
io.WriteString(h4, "aliyun_v4_request")
h4Key := h4.Sum(nil)
// Hasilkan tanda tangan.
h := hmac.New(hmacHash, h4Key)
io.WriteString(h, stringToSign)
signature := hex.EncodeToString(h.Sum(nil))
// Buat konten yang akan dikembalikan ke formulir frontend.
policyToken := PolicyToken{
Policy: stringToSign,
SecurityToken: *cred.SecurityToken,
SignatureVersion: "OSS4-HMAC-SHA256",
Credential: fmt.Sprintf("%v/%v/%v/%v/aliyun_v4_request", *cred.AccessKeyId, date, region, product),
Date: utcTime.UTC().Format("20060102T150405Z"),
Signature: signature,
Host: host, // URL ke mana data diunggah.
Dir: dir, // Direktori ke mana data diunggah.
}
response, err := json.Marshal(policyToken)
if err != nil {
fmt.Println("json err:", err)
}
return string(response)
}PHP
Jalankan perintah berikut untuk menginstal dependensi:
composer installAnda dapat merujuk pada kode contoh berikut untuk menyediakan kredensial akses sementara dan membuat kebijakan pengunggahan guna menghitung tanda tangan yang digunakan dalam permintaan PostObject:
<?php
// Gunakan SDK Alibaba Cloud.
require_once __DIR__ . '/vendor/autoload.php';
use AlibabaCloud\Client\AlibabaCloud;
use AlibabaCloud\Client\Exception\ClientException;
use AlibabaCloud\Client\Exception\ServerException;
use AlibabaCloud\Sts\Sts;
// Nonaktifkan tampilan kesalahan.
ini_set('display_errors', '0');
$bucket = 'examplebucket'; // Ganti nilai dengan nama bucket sebenarnya Anda.
$region_id = 'cn-hangzhou'; // Ganti nilai dengan ID wilayah tempat bucket berada.
$host = 'http://examplebucket.oss-cn-hangzhou.aliyuncs.com'; // Ganti nilai dengan URL bucket.
$expire_time = 3600; // Tentukan periode validitas dalam detik.
$upload_dir = 'user-dir'; // Tentukan awalan dalam nama objek.
// Hitung nilai HMAC-SHA256.
function hmacsha256($key, $data) {
return hash_hmac('sha256', $data, $key, true);
}
// Proses permintaan yang dimulai untuk mendapatkan tanda tangan.
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/get_post_signature_for_oss_upload') {
AlibabaCloud::accessKeyClient(getenv('OSS_ACCESS_KEY_ID'), getenv('OSS_ACCESS_KEY_SECRET'))
->regionId('cn-hangzhou')
->asDefaultClient();
// Buat permintaan untuk mendapatkan kredensial akses sementara dari STS.
$request = Sts::v20150401()->assumeRole();
// Mulai permintaan STS dan dapatkan hasilnya.
// Ganti <YOUR_ROLE_SESSION_NAME> dengan nama sesi kustom, seperti oss-role-session.
// Ganti <YOUR_ROLE_ARN> dengan ARN dari peran RAM yang memiliki izin untuk mengunggah objek ke bucket tertentu.
$result = $request
->withRoleSessionName('oss-role-session')
->withDurationSeconds(3600)
->withRoleArn(getenv('OSS_STS_ROLE_ARN'))
->request();
// Dapatkan informasi kredensial dalam hasil permintaan STS.
$tokenData = $result->get('Credentials');
// Bangun data JSON dari hasil yang dikembalikan.
$tempAccessKeyId = $tokenData['AccessKeyId'];
$tempAccessKeySecret = $tokenData['AccessKeySecret'];
$securityToken = $tokenData['SecurityToken'];
$now = time();
$dtObj = gmdate('Ymd\THis\Z', $now);
$dtObj1 = gmdate('Ymd', $now);
$dtObjPlus3h = gmdate('Y-m-d\TH:i:s.u\Z', strtotime('+3 hours', $now));
// Buat kebijakan.
$policy = [
"expiration" => $dtObjPlus3h,
"conditions" => [
["x-oss-signature-version" => "OSS4-HMAC-SHA256"],
["x-oss-credential" => "{$tempAccessKeyId}/{$dtObj1}/cn-hangzhou/oss/aliyun_v4_request"],
["x-oss-security-token" => $securityToken],
["x-oss-date" => $dtObj],
]
];
$policyStr = json_encode($policy);
// Buat string untuk ditandatangani.
$stringToSign = base64_encode($policyStr);
// Hitung kunci penandatanganan.
$dateKey = hmacsha256(('aliyun_v4' . $tempAccessKeySecret), $dtObj1);
$dateRegionKey = hmacsha256($dateKey, 'cn-hangzhou');
$dateRegionServiceKey = hmacsha256($dateRegionKey, 'oss');
$signingKey = hmacsha256($dateRegionServiceKey, 'aliyun_v4_request');
// Hitung tanda tangan.
$result = hmacsha256($signingKey, $stringToSign);
$signature = bin2hex($result);
// Kembalikan data tanda tangan.
$responseData = [
'policy' => $stringToSign,
'x_oss_signature_version' => "OSS4-HMAC-SHA256",
'x_oss_credential' => "{$tempAccessKeyId}/{$dtObj1}/cn-hangzhou/oss/aliyun_v4_request",
'x_oss_date' => $dtObj,
'signature' => $signature,
'host' => $host,
'dir' => $upload_dir,
'security_token' => $securityToken
];
header('Content-Type: application/json');
echo json_encode($responseData);
exit;
}
// Tentukan rute halaman utama.
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/') {
echo file_get_contents(__DIR__ . '/public/index.html');
exit;
}
// Tentukan rute lainnya.
http_response_code(404);
echo json_encode(['message' => 'Not Found']);
exit;
?>Langkah 3: Konfigurasikan Klien Web
Buat dan Kirim Permintaan Pengunggahan Formulir di Klien Web
Setelah klien web menerima informasi yang diperlukan dari server aplikasi, Anda dapat menggunakan informasi tersebut untuk membangun permintaan pengunggahan formulir HTML. Permintaan tersebut langsung dikirim ke OSS untuk mengunggah file.
Contoh Respons yang Diterima oleh Klien Web
Terima kredensial akses sementara dan kebijakan pengunggahan yang dikembalikan ke klien dari server aplikasi.
{
"dir": "user-dirs",
"host": "http://examplebucket.oss-cn-hangzhou.aliyuncs.com",
"policy": "eyJl****",
"security_token": "CAIS****",
"signature": "9103****",
"x_oss_credential": "STS.NSpW****/20241127/cn-hangzhou/oss/aliyun_v4_request",
"x_oss_date": "20241127T060941Z",
"x_oss_signature_version": "OSS4-HMAC-SHA256"
}Tabel berikut menjelaskan bidang-bidang yang termasuk dalam badan pesan.
Bidang | Deskripsi |
dir | Awalan yang terkandung dalam nama objek. |
host | URL bucket. |
policy | Kebijakan untuk pengunggahan formulir. Untuk informasi lebih lanjut, lihat Kebijakan. |
security_token | Token STS. |
signature | String tanda tangan kebijakan. Untuk informasi lebih lanjut, lihat Tanda Tangan POST. |
x_oss_credential | Parameter yang digunakan untuk menentukan kunci turunan. |
x_oss_date | Waktu saat permintaan dimulai. Waktu harus mengikuti standar ISO 8601. Contoh: |
x_oss_signature_version | Versi tanda tangan dan algoritma yang digunakan untuk menghitung tanda tangan. Nilainya tetap menjadi OSS4-HMAC-SHA256. |
Permintaan formulir berisi konten file dan parameter yang dikembalikan oleh server.
Klien web dapat langsung berkomunikasi dengan OSS dan mengunggah file menggunakan permintaan formulir.
Kecuali untuk bidang formulir file, ukuran setiap bidang formulir (termasuk kunci) tidak boleh melebihi 8 KB.
Secara default, objek yang ada dengan nama yang sama dengan objek yang Anda unggah akan ditimpa. Jika Anda tidak ingin menimpa objek yang ada, sertakan header x-oss-forbid-overwrite dalam permintaan pengunggahan dan atur header x-oss-forbid-overwrite ke true. Dengan cara ini, jika Anda mengunggah file dengan nama yang sama dengan objek yang ada di jalur tujuan, pengunggahan gagal dan OSS mengembalikan kode kesalahan FileAlreadyExists.
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Unggah Langsung ke OSS dengan Tanda Tangan dari Server Aplikasi</title>
</head>
<body>
<div class="container">
<form>
<div class="mb-3">
<label for="file" class="form-label">Pilih File:</label>
<input type="file" class="form-control" id="file" name="file" required />
</div>
<button type="submit" class="btn btn-primary">Unggah</button>
</form>
</div>
<script type="text/javascript">
document.addEventListener('DOMContentLoaded', function () {
const form = document.querySelector("form");
const fileInput = document.querySelector("#file");
form.addEventListener("submit", (event) => {
event.preventDefault();
const file = fileInput.files[0];
if (!file) {
alert('Pilih file untuk diunggah.');
return;
}
const filename = file.name;
fetch("/get_post_signature_for_oss_upload", { method: "GET" })
.then((response) => {
if (!response.ok) {
throw new Error("Gagal mendapatkan tanda tangan.");
}
return response.json();
})
.then((data) => {
let formData = new FormData();
formData.append("success_action_status", "200");
formData.append("policy", data.policy);
formData.append("x-oss-signature", data.signature);
formData.append("x-oss-signature-version", "OSS4-HMAC-SHA256");
formData.append("x-oss-credential", data.x_oss_credential);
formData.append("x-oss-date", data.x_oss_date);
formData.append("key", data.dir + file.name); // Nama file.
formData.append("x-oss-security-token", data.security_token);
formData.append("file", file); // Bidang formulir "file" harus menjadi yang terakhir.
return fetch(data.host, {
method: "POST",
body: formData
});
})
.then((response) => {
if (response.ok) {
console.log("Diunggah.");
alert("File berhasil diunggah.");
} else {
console.log("Pengunggahan gagal dengan respons berikut:", response);
alert("Gagal mengunggah file. Coba lagi nanti.");
}
})
.catch((error) => {
console.error("Terjadi kesalahan:", error);
});
});
});
</script>
</body>
</html>Formulir HTML berisi bidang input file dan tombol Kirim. Anda dapat memilih file untuk diunggah dan mengirimkan formulir.
Saat Anda mengirimkan formulir, pengiriman formulir default diblokir dengan menggunakan kode JavaScript, dan informasi tanda tangan yang diperlukan untuk pengunggahan diperoleh dari server menggunakan permintaan Asynchronous JavaScript and XML (AJAX).
Setelah Anda mendapatkan informasi tanda tangan, buat objek
FormDatayang berisi semua bidang formulir yang diperlukan.Anda dapat menggunakan metode
fetchuntuk mengirim permintaan POST ke URL bucket OSS.
Jika file berhasil diunggah, pesan "File berhasil diunggah." akan ditampilkan. Jika file gagal diunggah, pesan kesalahan akan ditampilkan.
Verifikasi Hasil
Setelah Anda menyelesaikan langkah-langkah sebelumnya, Anda dapat mengakses server aplikasi untuk menghasilkan tanda tangan dan mengunggah file dari klien web ke OSS.
Akses server melalui browser, lalu pilih dan unggah objek. Gambar berikut memberikan contoh.
Di halaman Buckets, klik nama bucket yang Anda buat untuk menyimpan objek yang diunggah. Di halaman yang muncul, lihat objek yang Anda unggah dari klien web.

Konfigurasi yang Disarankan
Batasi Izin dan Kondisi Pengunggahan File
Anda dapat memodifikasi bagian kebijakan dalam kode contoh untuk menentukan izin dan kondisi yang dimaksudkan untuk pengunggahan file ke OSS dari formulir HTML. Kebijakan untuk pengunggahan formulir mendefinisikan kondisi dalam format JSON yang harus dipenuhi oleh permintaan pengunggahan untuk mengamankan pengunggahan file dan memastikan kepatuhan. Misalnya, Anda dapat menggunakan kondisi untuk menentukan bucket tujuan untuk pengunggahan file, awalan nama objek, waktu kedaluwarsa, metode HTTP yang diizinkan, batas ukuran file, dan jenis file.
{
"expiration": "2023-12-03T13:00:00.000Z",
"conditions": [
{"bucket": "examplebucket"},
{"x-oss-signature-version": "OSS4-HMAC-SHA256"},
{"x-oss-credential": "AKIDEXAMPLE/20231203/cn-hangzhou/oss/aliyun_v4_request"},
{"x-oss-security-token": "CAIS******"},
{"x-oss-date": "20231203T121212Z"},
["content-length-range", 1, 10],
["eq", "$success_action_status", "201"],
["starts-with", "$key", "user/eric/"],
["in", "$content-type", ["image/jpg", "image/png"]],
["not-in", "$cache-control", ["no-cache"]]
]
}Untuk informasi lebih lanjut, lihat Kebijakan
Konfigurasikan Callback Pengunggahan
Jika Anda ingin mendapatkan lebih banyak informasi tentang objek yang diunggah, seperti nama objek dan ukurannya, Anda dapat mengonfigurasi callback pengunggahan. Dengan cara ini, informasi tentang file secara otomatis diterima setelah file diunggah. Untuk informasi lebih lanjut, lihat Tambahkan tanda tangan di server, konfigurasikan callback pengunggahan, dan transfer data langsung.
Sertakan URL Server Aplikasi dalam Sumber Pengaturan CORS
Sebelumnya dalam langkah konfigurasi CORS, kami menentukan karakter wildcard * untuk mengizinkan akses dari semua sumber. Untuk alasan keamanan, kami sarankan Anda membatasi sumber yang diizinkan. Misalnya, Anda dapat menentukan URL server aplikasi Anda sebagai satu-satunya sumber yang diizinkan. Dengan cara ini, akses lintas domain hanya diizinkan untuk permintaan dari server aplikasi Anda.
Parameter | Nilai Contoh |
Source |
|
Allowed Methods | POST, PUT, dan GET |
Allowed Headers | * |
Pembersihan Sumber Daya
Untuk membangun aplikasi web, Anda telah membuat instance ECS, bucket OSS, pengguna RAM, dan peran RAM. Setelah Anda menyelesaikan verifikasi, Anda dapat melepaskan sumber daya ini untuk menghindari biaya yang tidak perlu dan menghilangkan risiko keamanan terkait.
Lepaskan Instance ECS
Jika Anda tidak lagi membutuhkan instance ECS yang Anda buat, Anda dapat melepaskannya. Setelah instance ECS dilepaskan, penagihan untuk instance berhenti, dan data pada instance hilang dan tidak dapat dipulihkan. Untuk melepaskan instance ECS, lakukan langkah-langkah berikut:
Pergi ke halaman Instance di ECS console, temukan instance ECS berdasarkan wilayah dan ID-nya, lalu klik ikon
di kolom Actions.Pilih Instance Status > Release.

Di kotak dialog Lepas, pilih Release Now untuk Pengaturan Lepas dan klik Next.
Konfirmasi sumber daya terkait yang ingin Anda lepaskan, baca catatan tentang risiko kehilangan data, centang kotak "Saya mengetahui instance dan sumber daya terkait yang akan dilepaskan serta memahami risiko data", lalu klik OK.
Saat instance ECS dilepaskan, disk sistem dari instance tersebut juga dilepaskan. Jika alamat IP publik telah ditetapkan ke instance, alamat IP tersebut juga dilepaskan.
Saat instance ECS dilepaskan, grup keamanan terkait, vSwitch, dan VPC tidak dilepaskan. Anda tidak dikenakan biaya untuk grup keamanan, vSwitch, atau VPC. Anda dapat mempertahankan atau melepaskannya berdasarkan kebutuhan bisnis Anda.
Jika EIP terkait dengan instance ECS, EIP dipertahankan saat instance dilepaskan. Anda akan dikenakan biaya untuk EIP. Anda dapat mempertahankan atau melepaskan EIP berdasarkan kebutuhan bisnis Anda.
Hapus bucket
Masuk ke Konsol OSS.
Di panel navigasi sisi kiri, klik Buckets. Di halaman Buckets, klik nama bucket yang ingin Anda hapus.
Hapus semua objek dalam bucket, lalu hapus bucket tersebut.
Di pohon navigasi sisi kiri, klik Delete Bucket. Di halaman Hapus Bucket, klik Hapus Bucket dan ikuti petunjuk di layar untuk menyelesaikan operasi penghapusan.
Hapus Pengguna RAM
Masuk ke Konsol RAM sebagai pengguna RAM yang memiliki hak admin.
Di panel navigasi sisi kiri, pilih Identities > Users.
Di halaman Users, temukan pengguna RAM yang ingin Anda hapus dan klik Delete di kolom Actions.
Anda juga dapat memilih beberapa pengguna RAM dan klik Delete User di bawah daftar pengguna RAM untuk memindahkan semua pengguna RAM yang dipilih ke tempat sampah secara bersamaan.
Di kotak dialog Delete User, baca pernyataan tentang dampak penghapusan, masukkan nama pengguna RAM, lalu klik Move to Recycle Bin.
Hapus Peran RAM
Masuk ke Konsol RAM sebagai pengguna RAM yang memiliki hak admin.
Di panel navigasi sisi kiri, pilih Identities > Roles.
Di halaman Roles, temukan peran RAM yang ingin Anda hapus dan klik Delete Role di kolom Actions.
Di kotak dialog Delete Role, masukkan nama peran RAM dan klik Delete Role.
CatatanJika kebijakan dilampirkan ke peran RAM, kebijakan tersebut dilepaskan saat Anda menghapus peran RAM.
Referensi
Apakah solusi pengunggahan langsung ini mendukung pengunggahan multipart dan pengunggahan yang dapat dilanjutkan?
Tidak, solusi ini tidak mendukung unggah multi-bagian atau unggah yang dapat dilanjutkan karena file diunggah menggunakan formulir HTML. Untuk informasi tentang cara menerapkan unggah multi-bagian atau unggah yang dapat dilanjutkan, lihat Unggah yang dapat dilanjutkan dan Unggah multi-bagian.
Bagaimana cara mencegah pengunggahan file menimpa objek yang ada di jalur tujuan OSS?
Jika Anda ingin mencegah pengunggahan file menimpa objek yang ada di jalur tujuan OSS, Anda dapat menambahkan header x-oss-forbid-overwrite dalam permintaan dan atur nilainya menjadi true. Contohnya:
formData.append('x-oss-forbid-overwrite', 'true');