Operasi PostObject memungkinkan Anda mengunggah file langsung dari klien web ke Object Storage Service (OSS). Operasi ini menggunakan tanda tangan yang dihasilkan oleh server demi keamanan dan memungkinkan Anda mengonfigurasi kebijakan untuk membatasi unggahan sesuai kebutuhan bisnis.
Ikhtisar solusi
Untuk menerapkan unggah langsung dengan penandatanganan sisi server, ikuti tiga langkah berikut:
Penggunaan kredensial akses sementara mencegah terpaparnya kunci jangka panjang server Anda, sehingga meningkatkan keamanan unggah file.
-
Konfigurasikan OSS: Buat bucket di konsol untuk menyimpan file pengguna. Lalu, konfigurasikan aturan Cross-Origin Resource Sharing (CORS) pada bucket tersebut agar mengizinkan permintaan lintas asal dari klien web.
-
Konfigurasikan server: Panggil Security Token Service (STS) untuk mendapatkan kredensial akses sementara. Gunakan kredensial ini beserta kebijakan unggah sisi server untuk menghasilkan tanda tangan. Kebijakan mencakup parameter seperti nama bucket, jalur direktori, dan waktu kedaluwarsa. Tanda tangan ini memberi otorisasi kepada pengguna untuk mengunggah file dalam periode tertentu.
-
Konfigurasikan klien web: Susun permintaan formulir HTML dan gunakan tanda tangan tersebut untuk mengunggah file ke OSS.
Proyek contoh
-
Untuk proyek contoh Java, lihat server-signed-direct-upload-java.zip.
-
Untuk proyek contoh Python, lihat server-signed-direct-upload-python.zip.
-
Untuk proyek contoh Node.js, lihat server-signed-direct-upload-nodejs.zip.
-
Untuk proyek contoh Go, lihat server-signed-direct-upload-go.zip.
-
Untuk proyek contoh PHP, lihat server-signed-direct-upload-php.zip.
Langkah-langkah
Langkah 1: Konfigurasikan OSS
Buat bucket
Buat bucket OSS untuk menyimpan file yang diunggah langsung dari browser web.
-
Login ke Konsol OSS.
-
Di panel navigasi sebelah kiri, klik Buckets, lalu klik Create Bucket.
-
Di panel Create Bucket, pilih Quick Create dan konfigurasikan parameter berikut:
Parameter
Nilai contoh
Bucket Name
web-direct-upload
Region
China (Hangzhou)
-
Klik Create.
Konfigurasikan aturan CORS
Konfigurasikan aturan CORS untuk bucket OSS Anda.
-
Di halaman Buckets, klik bucket target.
-
Di halaman CORS, klik Create Rule.
-
Di panel Create Rule, atur parameter berikut.
Parameter
Nilai contoh
Origin
*
Allowed Methods
POST, PUT, GET
Allowed Headers
*
-
Klik OK.
Langkah 2: Konfigurasikan server
Untuk penerapan produksi, jika Anda sudah memiliki server, lewati persiapan dan langsung ke 1. Konfigurasikan izin pengguna.
Buat instance ECS
Langkah 1: Buat instance ECS
Buka halaman Custom Launch dan pilih sumber daya dasar yang diperlukan untuk membuat instance ECS.
-
Pilih wilayah dan metode penagihan
-
Pilih metode penagihan sesuai kebutuhan bisnis Anda. Tutorial ini menggunakan mode pay-as-you-go karena fleksibilitasnya.
-
Umumnya, memilih wilayah yang lebih dekat dengan pengguna Anda menghasilkan latensi jaringan lebih rendah dan akses lebih cepat. Tutorial ini menggunakan China (Hangzhou) sebagai contoh.
Untuk Billing Method, pilih pay-as-you-go (post-paid dan on-demand). Instance pay-as-you-go tidak mendukung Pendaftaran ICP. Setelah instance dibuat, wilayahnya tidak dapat diubah. Instance di wilayah berbeda tidak dapat berkomunikasi melalui jaringan internal.
-
-
Buat Virtual Private Cloud (VPC) dan vSwitch
Saat membuat VPC, pilih wilayah yang sama dengan instance ECS dan rencanakan Blok CIDR sesuai kebutuhan bisnis Anda. Tutorial ini menggunakan pembuatan VPC dan vSwitch di wilayah China (Hangzhou) sebagai contoh. Setelah membuat VPC dan vSwitch, kembali ke halaman pembelian ECS, refresh, lalu pilih keduanya.
CatatanAnda dapat membuat vSwitch saat membuat VPC.

Di halaman Create VPC, atur Name menjadi ProjectA-VPC, pilih Manually Specify IPv4 CIDR Block untuk IPv4 CIDR Block dan masukkan
192.168.0.0/16, serta pilih Do Not Assign untuk IPv6 CIDR Block.Contoh konfigurasi vSwitch: Atur Name menjadi ProjectA-vSwitch, pilih Hangzhou Zone H untuk Zone, atur IPv4 CIDR Block menjadi
192.168.10.0/24, lalu klik OK.
-
Pilih tipe instans dan gambar
Pilih tipe instans dan gambar. Gambar menentukan sistem operasi dan versinya yang diinstal pada instans. Tutorial ini menggunakan tipe instans
ecs.e-c1m1.large, yang hemat biaya dan memenuhi kebutuhan pengujian. Gambarnya adalah gambar publikAlibaba Cloud Linux 3.2104 LTS 64-bit.
-
Konfigurasikan penyimpanan
Untuk sistem web sederhana dalam tutorial ini, disk sistem sudah cukup untuk sistem operasi, sehingga disk data tidak diperlukan.
Untuk disk sistem, pilih ESSD, atur Performance Level ke PL0 dan Kapasitas ke 40 GiB, pilih Release with Instance, dan jangan tambahkan disk data.
-
Tetapkan alamat IP publik
Untuk kesederhanaan, tutorial ini langsung menetapkan alamat IP publik ke instans. Sebagai alternatif, Anda dapat mengaitkan Elastic IP Address (EIP) ke instans setelah membuatnya. Untuk informasi selengkapnya, lihat Associate an EIP with a cloud resource.
Catatan-
Jika alamat IP publik tidak ditetapkan, Anda tidak dapat menggunakan SSH atau Protokol Desktop Jarak Jauh (RDP) untuk mengakses instans secara langsung dari internet, maupun memverifikasi penerapan layanan web pada instans tersebut.
-
Tutorial ini menggunakan metode penagihan bandwidth pay-by-traffic. Metode ini hanya menagih Anda berdasarkan trafik publik yang dikonsumsi. Untuk informasi selengkapnya, lihat Public bandwidth billing.
Atur Peak bandwidth menjadi 5 Mbps.
-
-
Buat grup keamanan
Buat grup keamanan untuk instans tersebut. Grup keamanan adalah firewall virtual yang mengontrol lalu lintas arah masuk dan keluar untuk instance ECS. Saat membuat grup keamanan, izinkan lalu lintas pada port berikut agar Anda dapat mengakses instance ECS nanti.
Port range: SSH (22), RDP (3389), HTTP (80), dan HTTPS (443).
Catatan-
Port yang dipilih untuk Port range diperlukan untuk aplikasi yang berjalan pada instance ECS.
-
Secara default, grup keamanan yang dibuat di sini mencakup aturan yang mengatur sumber ke 0.0.0.0/0. Hal ini mengizinkan akses dari alamat IP mana pun ke port yang ditentukan. Jika Anda mengetahui alamat IP klien yang melakukan permintaan, kami menyarankan agar Anda kemudian membatasi sumber ke rentang IP tertentu. Untuk informasi selengkapnya, lihat Modify a security group rule.
Di bagian Security group type, pilih Basic security group.
-
-
Buat pasangan kunci
-
Pasangan kunci menyediakan kredensial logon yang aman. Setelah membuat pasangan kunci, Anda harus mengunduh kunci privatnya, yang diperlukan untuk menghubungkan ke instance ECS. Lalu, kembali ke halaman pembelian ECS, refresh, dan pilih pasangan kunci tersebut.
-
Pengguna
rootmemiliki hak istimewa tertinggi dalam sistem operasi, dan menggunakanrootsebagai nama login dapat menimbulkan risiko keamanan. Kami menyarankan agar Anda menggunakanecs-usersebagai nama login.CatatanSetelah Anda membuat pasangan kunci, kunci privat akan diunduh secara otomatis. Simpan file kunci privat
.pemdari riwayat unduhan browser Anda.Di bagian Logon Credential, pilih tab Key pair, klik Create key pair. Lalu, pilih pasangan kunci yang baru dibuat (misalnya,
ecs-test) dari daftar drop-down Key pair.
-
-
Buat dan lihat instance ECS
Setelah memilih sumber daya yang diperlukan untuk instance ECS, klik Create order. Di kotak dialog sukses, klik Management console untuk melihat instance baru. Simpan informasi berikut untuk digunakan nanti:
-
Instance ID: Digunakan untuk menemukan instance di daftar instance.
-
Region: Digunakan untuk menemukan instance di daftar instance.
-
Public IP address: Digunakan untuk memverifikasi penerapan layanan web.
-
Langkah 2: Hubungkan ke instance ECS
-
Di halaman Instances Konsol ECS, temukan instance Anda menggunakan wilayah dan ID-nya, lalu di kolom Actions, klik Connect.
-
Di kotak dialog Remote connection, klik Sign in now di samping Workbench.
-
Di kotak dialog Log on to instance, pilih Terminal connection untuk Connection method dan SSH key authentication untuk Authentication method. Lalu, masukkan atau unggah file kunci privat Anda, dan klik Log on untuk terhubung sebagai pengguna
ecs-user. -
Catatan
File kunci privat (
.pem) diunduh secara otomatis ke perangkat Anda saat membuat pasangan kunci. Periksa riwayat unduhan browser Anda untuk menemukan file tersebut. -
Saat output berikut ditampilkan, Anda telah berhasil login ke instance ECS.
Welcome to Alibaba Cloud Elastic Compute Service ! Last login: Sun Sep 29 15:35:22 2024 from xxx [ecs-user@iz*** ~]$
Izin pengguna
Untuk mencegah unggahan OSS gagal setelah penerapan akibat izin yang tidak mencukupi, buat pengguna RAM dan konfigurasikan izin yang diperlukan.
Langkah 1: Buat Pengguna RAM
Buat pengguna RAM dan dapatkan Pasangan Kunci Aksesnya untuk dijadikan kredensial jangka panjang bagi server aplikasi Anda.
-
Login ke Konsol RAM dengan Akun Alibaba Cloud Anda atau sebagai administrator RAM.
-
Di panel navigasi sebelah kiri, pilih Identities > Users.
-
Klik Create User.
-
Masukkan Logon Name dan Display Name.
-
Di bagian Access Mode, pilih Programmatic access, lalu klik OK.
Rahasia AccessKey hanya ditampilkan saat pembuatan dan tidak dapat diambil kembali nanti. Simpan dengan aman.
-
Di kolom Actions, klik Copy untuk menyimpan Pasangan Kunci Akses (ID AccessKey dan Rahasia AccessKey).
Langkah 2: Berikan izin AssumeRole
Setelah membuat pengguna RAM, berikan izin untuk memanggil operasi STS AssumeRole. Hal ini memungkinkan pengguna memperoleh kredensial sementara dengan mengasumsikan peran RAM.
-
Di panel navigasi sebelah kiri, pilih Identities > Users.
-
Di halaman Users, temukan pengguna RAM target, lalu klik Add Permissions di kolom Actions.
-
Di halaman Grant Permission, pilih Kebijakan Sistem AliyunSTSAssumeRoleAccess.
CatatanKebijakan AliyunSTSAssumeRoleAccess memberikan izin untuk memanggil operasi
AssumeRole. Kebijakan ini tidak memberikan izin untuk operasi selanjutnya yang menggunakan kredensial sementara, seperti permintaan OSS. -
Klik OK.
Langkah 3: Buat peran RAM
Buat peran RAM untuk Akun Alibaba Cloud saat ini dan dapatkan Nama Sumber Daya Alibaba Cloud (ARN)-nya. Pengguna RAM akan mengasumsikan peran ini.
-
Di panel navigasi sebelah kiri, pilih Identities > Roles.
-
Klik Create Role. Untuk Principal Type, pilih Alibaba Cloud Account.
-
Pilih Akun Alibaba Cloud saat ini dan klik OK.
-
Masukkan nama peran dan klik OK.
-
Di halaman detail peran RAM, klik Copy untuk menyimpan ARN peran tersebut.
Langkah 4: Buat kebijakan unggah file
Dengan mengikuti prinsip hak istimewa minimal, buat Kebijakan Kustom untuk peran RAM yang membatasi unggahan ke bucket OSS tertentu.
-
Di panel navigasi sebelah kiri, pilih Permissions > Policies.
-
Klik Create Policy.
-
Di halaman Create Policy, klik JSON Editor dan ganti
<Bucket name>dalam skrip dengan nama bucketweb-direct-uploadyang Anda buat di bagian Persiapan.{ "Version": "1", "Statement": [ { "Effect": "Allow", "Action": "oss:PutObject", "Resource": "acs:oss:*:*:<BucketName>/*" } ] } -
Setelah mengonfigurasi kebijakan, klik OK.
-
Di kotak dialog Create Policy, masukkan Policy Name dan klik OK.
Langkah 5: Berikan izin kepada peran RAM
Berikan Kebijakan Kustom yang Anda buat kepada peran RAM. Hal ini memberikan izin yang diperlukan kepada peran yang diasumsikan.
-
Di panel navigasi sebelah kiri, pilih Identities > Roles.
-
Di halaman Roles, temukan peran RAM target, lalu klik Add Permissions di kolom Actions.
-
Di halaman Grant Permission, pilih Custom Policy, lalu pilih kebijakan yang Anda buat.
-
Klik OK.
Penandatanganan sisi server
Kami menyarankan mengonfigurasi informasi sensitif, seperti AccessKey ID, AccessKey Secret, dan Role ARN, sebagai variabel lingkungan. Praktik ini menghindari hardcoding dalam kode Anda dan mengurangi risiko kebocoran kredensial.
Ikuti langkah-langkah berikut untuk mengatur variabel lingkungan.
Linux
-
Dari command line, jalankan perintah berikut untuk menambahkan pengaturan 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'" >> ~/.bashrc -
Jalankan perintah berikut untuk menerapkan perubahan.
source ~/.bashrc -
Jalankan perintah berikut untuk memverifikasi bahwa variabel lingkungan telah diatur.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET echo $OSS_STS_ROLE_ARN
macOS
-
Di terminal, jalankan perintah berikut untuk memeriksa shell default Anda.
echo $SHELL -
Ikuti petunjuk untuk shell default Anda.
Zsh
-
Jalankan perintah berikut untuk menambahkan pengaturan variabel lingkungan ke file
~/.zshrc.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'" >> ~/.zshrc -
Jalankan perintah berikut untuk menerapkan perubahan.
source ~/.zshrc -
Jalankan perintah berikut untuk memverifikasi bahwa variabel lingkungan telah diatur.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET echo $OSS_STS_ROLE_ARN
Bash
-
Jalankan perintah berikut untuk menambahkan pengaturan variabel lingkungan ke file
~/.bash_profile.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_profile -
Jalankan perintah berikut untuk menerapkan perubahan.
source ~/.bash_profile -
Jalankan perintah berikut untuk memverifikasi bahwa variabel lingkungan telah diatur.
echo $OSS_ACCESS_KEY_ID echo $OSS_ACCESS_KEY_SECRET echo $OSS_STS_ROLE_ARN
-
Windows
-
Jalankan perintah berikut di Command Prompt (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.
-
Di jendela CMD baru, jalankan perintah berikut untuk memverifikasi bahwa variabel lingkungan telah diatur.
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET% echo %OSS_STS_ROLE_ARN%
Gunakan kode contoh berikut untuk menghitung tanda tangan POST di server dengan Signature Version 4 (direkomendasikan). Untuk informasi selengkapnya tentang mengonfigurasi bidang formulir kebijakan, lihat policy form field.
Java
Tambahkan dependensi berikut ke proyek Maven Anda.
<!-- 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>
Kode contoh berikut menunjukkan cara mendapatkan kredensial akses sementara dan menghitung tanda tangan POST di server:
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 dasar OSS. Ganti dengan nama bucket, ID wilayah, dan host aktual Anda.
String bucket = "examplebucket";
String region = "cn-hangzhou";
String host = "http://examplebucket.oss-cn-hangzhou.aliyuncs.com";
// Atur URL callback unggahan, yaitu alamat server callback Anda. Ini harus berupa URL publik. OSS menggunakan URL ini untuk mengirim informasi unggahan objek ke server aplikasi Anda.
// Awalan (direktori) untuk objek yang akan diunggah ke OSS.
String upload_dir = "dir";
// Waktu kedaluwarsa dalam detik.
Long expire_time = 3600L;
/**
* Menghasilkan waktu kedaluwarsa berdasarkan durasi tertentu dalam detik.
* @param seconds Durasi dalam detik.
* @return String waktu ISO 8601, seperti "2014-12-01T12:00:00.000Z".
*/
public static String generateExpiration(long seconds) {
// Dapatkan timestamp saat ini dalam detik.
long now = Instant.now().getEpochSecond();
// Hitung timestamp kedaluwarsa.
long expirationTime = now + seconds;
// Konversi timestamp ke objek Instant dan format ke ISO 8601.
Instant instant = Instant.ofEpochSecond(expirationTime);
// Tentukan zona waktu sebagai UTC.
ZoneId zone = ZoneOffset.UTC;
// Konversi Instant ke ZonedDateTime.
ZonedDateTime zonedDateTime = instant.atZone(zone);
// Tentukan format tanggal-waktu, misalnya, 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 klien STS.
public static com.aliyun.sts20150401.Client createStsClient() throws Exception {
// Hardcoding Pasangan Kunci Akses merupakan risiko keamanan dan tidak disarankan. Kode ini hanya untuk referensi.
com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
// Wajib. Pastikan variabel lingkungan OSS_ACCESS_KEY_ID diatur di lingkungan runtime kode Anda.
.setAccessKeyId(System.getenv("OSS_ACCESS_KEY_ID"))
// Wajib. Pastikan variabel lingkungan OSS_ACCESS_KEY_SECRET diatur di lingkungan runtime kode Anda.
.setAccessKeySecret(System.getenv("OSS_ACCESS_KEY_SECRET"));
// Untuk informasi selengkapnya tentang titik akhir, lihat https://api.aliyun.com/product/Sts.
config.endpoint = "sts.cn-hangzhou.aliyuncs.com";
return new com.aliyun.sts20150401.Client(config);
}
/**
* Dapatkan kredensial sementara 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()
// Wajib. Pastikan variabel lingkungan OSS_STS_ROLE_ARN diatur di lingkungan runtime kode Anda.
.setRoleArn(System.getenv("OSS_STS_ROLE_ARN"))
.setRoleSessionName("yourRoleSessionName");// Nama sesi kustom.
com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
try {
// Jika Anda menyalin kode ini untuk dijalankan, cetak nilai kembali API.
AssumeRoleResponse response = client.assumeRoleWithOptions(assumeRoleRequest, runtime);
// Objek kredensial berisi AccessKeyId, AccessKeySecret, dan SecurityToken.
return response.body.credentials;
} catch (TeaException error) {
// Ini hanya untuk demonstrasi. Tangani pengecualian dengan hati-hati dan jangan abaikan dalam proyek Anda.
// Pesan error
System.out.println(error.getMessage());
// Alamat diagnostik
System.out.println(error.getData().get("Recommend"));
com.aliyun.teautil.Common.assertAsString(error.message);
}
// Kembalikan objek respons error default untuk menghindari pengembalian 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 untuk x-oss-credential. Ini adalah tanggal saat ini dalam format yyyyMMdd.
ZonedDateTime today = ZonedDateTime.now().withZoneSameInstant(java.time.ZoneOffset.UTC);
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
String date = today.format(formatter);
// Dapatkan 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 dengan ID AccessKey aktual 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: Susun string yang akan 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 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 ResponseEntity dengan kode status 200 (OK) ke klien web untuk operasi PostObject.
return ResponseEntity.ok(response);
}
public static byte[] hmacsha256(byte[] key, String data) {
try {
// Inisialisasi spesifikasi kunci HmacSHA256.
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "HmacSHA256");
// Dapatkan instance Mac HmacSHA256.
Mac mac = Mac.getInstance("HmacSHA256");
// Inisialisasi objek Mac dengan kunci.
mac.init(secretKeySpec);
// Hitung tanda tangan HMAC untuk data.
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_credentials
Kode contoh berikut menunjukkan cara mendapatkan kredensial akses sementara (token STS), menyusun kebijakan unggahan, dan menghitung tanda tangan POST di server.
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')
# Nama sesi kustom.
role_session_name = 'yourRoleSessionName'
# Ganti dengan nama bucket, ID wilayah, dan host Anda yang sebenarnya.
bucket = 'examplebucket'
region_id = 'cn-hangzhou'
host = 'http://examplebucket.oss-cn-hangzhou.aliyuncs.com'
# Waktu kedaluwarsa dalam detik.
expire_time = 3600
# Awalan (direktori) untuk objek yang akan diunggah ke OSS.
upload_dir = 'dir'
def hmacsha256(key, data):
"""
Menghitung nilai hash HMAC-SHA256.
:param key: Kunci untuk menghitung hash, dalam byte.
:param data: Data yang akan di-hash, sebagai string.
:return: Nilai hash HMAC-SHA256 yang dihitung, dalam 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 dan teruskan kredensial secara langsung.
config = Config(
region_id=region_id,
access_key_id=access_key_id,
access_key_secret=access_key_secret
)
# Buat klien STS dan dapatkan kredensial 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 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())
# Konversikan stempel waktu menjadi objek datetime.
dt_obj = datetime.datetime.utcfromtimestamp(now)
# Tambahkan 3 jam ke waktu saat ini untuk mengatur waktu kedaluwarsa permintaan.
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 yang akan 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()
# Buat data tanggapan.
response_data = {
'policy': stringToSign, # Bidang formulir kebijakan.
'x_oss_signature_version': "OSS4-HMAC-SHA256", # Versi dan algoritma tanda tangan. Ini ditetapkan ke OSS4-HMAC-SHA256.
'x_oss_credential': f"{temp_access_key_id}/{dt_obj_2}/cn-hangzhou/oss/aliyun_v4_request", # Menentukan cakupan kredensial.
'x_oss_date': dt_obj_1, # Waktu permintaan.
'signature': signature, # Tanda tangan yang dihitung.
'host': host,
'dir': upload_dir,
'security_token': security_token # Token keamanan.
}
return jsonify(response_data)
if __name__ == "__main__":
app.run(host="127.0.0.1", port=8000) # Jika Anda perlu mendengarkan di alamat lain seperti 0.0.0.0, Anda harus menambahkan mekanisme otentikasi sisi server.
Node.js
Jalankan perintah berikut untuk menginstal dependensi.
npm install ali-oss
npm install @alicloud/credentials
npm install express
Kode contoh berikut menunjukkan cara mendapatkan kredensial akses sementara (token STS), menyusun kebijakan unggahan, dan menghitung tanda tangan POST di server.
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; // Nomor port untuk permintaan layanan.
// Atur direktori file statis.
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 STS sementara.
const result = await sts.assumeRole(process.env.OSS_STS_ROLE_ARN, '', '3600', 'yourRoleSessionName'); // Dapatkan ARN peran RAM dari variabel lingkungan. Kredensial akses sementara berlaku selama 3.600 detik, dan nama sesi peran adalah nilai kustom, seperti yourRoleSessionName.
// Ekstrak AccessKeyId, AccessKeySecret, dan SecurityToken dari kredensial akses sementara.
const accessKeyId = result.credentials.AccessKeyId;
const accessKeySecret = result.credentials.AccessKeySecret;
const securityToken = result.credentials.SecurityToken;
// Inisialisasi klien OSS.
const client = new OSS({
bucket: 'examplebucket', // Ganti dengan nama bucket tujuan.
region: 'cn-hangzhou', // Ganti dengan wilayah bucket tujuan.
accessKeyId,
accessKeySecret,
stsToken: securityToken,
refreshSTSTokenInterval: 0,
refreshSTSToken: async () => {
const { accessKeyId, accessKeySecret, securityToken } = await client.getCredential();
return { accessKeyId, accessKeySecret, stsToken: securityToken };
},
});
// Buat map data formulir.
const formData = new Map();
// Atur waktu kedaluwarsa tanda tangan menjadi 10 menit dari waktu saat ini.
const date = new Date();
const expirationDate = new Date(date);
expirationDate.setMinutes(date.getMinutes() + 10);
// Format tanggal ke string waktu UTC yang sesuai dengan 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);
// Hasilkan x-oss-credential dan atur 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.
// Kebijakan contoh ini hanya mencantumkan kondisi yang diperlukan.
const policy = {
expiration: expirationDate.toISOString(),
conditions: [
{ 'bucket': 'examplebucket'},
{ 'x-oss-credential': credential },
{ 'x-oss-signature-version': 'OSS4-HMAC-SHA256' },
{ 'x-oss-date': formattedDate },
],
};
// Jika ada token STS, 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 atur 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', // Awalan (direktori) untuk objek yang akan diunggah 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}`); // Jika Anda perlu mendengarkan alamat lain seperti 0.0.0.0, Anda harus menambahkan mekanisme autentikasi sisi server.
});
Go
Jalankan perintah berikut untuk menginstal dependensi.
go get -u github.com/aliyun/credentials-go
go mod tidy
Kode contoh berikut menunjukkan cara mendapatkan kredensial akses sementara (token STS), menyusun kebijakan unggahan, dan menghitung tanda tangan POST di server.
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"
)
// Struktur PolicyToken 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() {
// Definisikan string alamat 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)
}
// Cetak alamat dan port tempat server berjalan.
fmt.Printf("server is running on %s \n", strIPPort)
// Daftarkan fungsi untuk menangani permintaan jalur root.
http.HandleFunc("/", handlerRequest)
// Daftarkan fungsi untuk menangani permintaan pembuatan 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)
}
}
// Fungsi handlerRequest menangani permintaan 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)
}
// Fungsi handleGetPostSignature menangani permintaan pembuatan 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 asal.
w.Write([]byte(response))
return
}
http.NotFound(w, r)
}
// Fungsi getPolicyToken menghasilkan tanda tangan dan kredensial yang diperlukan untuk unggahan OSS.
func getPolicyToken() string {
// Atur wilayah bucket.
region = "cn-hangzhou"
// Ganti dengan nama bucket Anda.
bucketName = "examplebucket"
// Atur alamat unggahan OSS.
host := fmt.Sprintf("https://%s.oss-%s.aliyuncs.com", bucketName, region)
// Atur direktori unggahan.
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 dari penyedia kredensial.
cred, err := provider.GetCredential()
if err != nil {
log.Fatalf("GetCredential fail, err:%v", err)
}
// Susun 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-date": utcTime.Format("20060102T150405Z")},
map[string]string{"x-oss-security-token": *cred.SecurityToken},
},
}
// Konversi kebijakan ke format JSON.
policy, err := json.Marshal(policyMap)
if err != nil {
log.Fatalf("json.Marshal fail, err:%v", err)
}
// Susun string yang akan ditandatangani.
stringToSign := base64.StdEncoding.EncodeToString([]byte(policy))
hmacHash := func() hash.Hash { return sha256.New() }
// Susun 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))
// Susun formulir yang akan dikembalikan ke klien.
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, // Alamat unggahan OSS.
Dir: dir, // Direktori unggahan.
}
response, err := json.Marshal(policyToken)
if err != nil {
fmt.Println("json err:", err)
}
return string(response)
}
PHP
Jalankan perintah berikut untuk menginstal dependensi.
composer install
Kode contoh berikut menunjukkan cara mendapatkan kredensial akses sementara (token STS), menyusun kebijakan unggahan, dan menghitung tanda tangan POST di server.
<?php
// Impor 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 error.
ini_set('display_errors', '0');
$bucket = 'examplebucket'; // Ganti dengan nama bucket Anda.
$region_id = 'cn-hangzhou'; // Ganti dengan wilayah bucket Anda.
$host = 'http://examplebucket.oss-cn-hangzhou.aliyuncs.com'; // Ganti dengan nama domain bucket Anda.
$expire_time = 3600; // Waktu kedaluwarsa dalam detik.
$upload_dir = 'user-dir'; // Awalan (direktori) untuk objek yang diunggah.
// Hitung HMAC-SHA256.
function hmacsha256($key, $data) {
return hash_hmac('sha256', $data, $key, true);
}
// Tangani permintaan untuk mendapatkan tanda tangan POST.
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 STS.
$request = Sts::v20150401()->assumeRole();
// Mulai permintaan STS dan dapatkan hasilnya.
// Atur <YOUR_ROLE_SESSION_NAME> ke nama sesi kustom, seperti oss-role-session.
// Ganti <YOUR_ROLE_ARN> dengan ARN peran RAM yang memiliki izin untuk mengunggah file ke bucket OSS yang ditentukan.
$result = $request
->withRoleSessionName('oss-role-session')
->withDurationSeconds(3600)
->withRoleArn(getenv('OSS_STS_ROLE_ARN'))
->request();
// Dapatkan informasi kredensial dari hasil permintaan STS.
$tokenData = $result->get('Credentials');
// Susun data JSON yang akan 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));
// Susun 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);
// Susun string yang akan 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;
}
// Rute halaman utama.
if ($_SERVER['REQUEST_METHOD'] === 'GET' && $_SERVER['REQUEST_URI'] === '/') {
echo file_get_contents(__DIR__ . '/public/index.html');
exit;
}
// Rute lainnya.
http_response_code(404);
echo json_encode(['message' => 'Not Found']);
exit;
?>
Langkah 3: Konfigurasikan klien web
Unggah formulir sisi klien
Setelah klien web menerima informasi yang diperlukan dari server aplikasi, klien tersebut membangun permintaan formulir HTML. Permintaan ini berkomunikasi langsung dengan OSS untuk mengunggah file.
Klien web: Respons contoh
Server aplikasi mengembalikan token STS dan kebijakan unggahan ke klien web.
{
"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 setiap bidang dalam badan respons.
|
Parameter |
Deskripsi |
|
dir |
Menentukan awalan nama objek yang diperlukan untuk unggahan. |
|
host |
Nama domain bucket tujuan. |
|
policy |
Kebijakan yang digunakan untuk unggahan formulir berbasis browser. Untuk informasi selengkapnya, lihat Post Policy. |
|
security_token |
Kredensial sementara yang digunakan untuk otentikasi, disediakan oleh STS. |
|
signature |
Tanda tangan yang dihasilkan dari kebijakan. Untuk informasi selengkapnya, lihat Post Signature. |
|
x_oss_credential |
Menentukan set parameter yang digunakan untuk menurunkan kunci penandatanganan. |
|
x_oss_date |
Waktu permintaan dalam format ISO 8601, misalnya, |
|
x_oss_signature_version |
Versi dan algoritma tanda tangan. Nilainya tetap OSS4-HMAC-SHA256. |
-
Permintaan formulir mencakup konten file dan parameter yang dikembalikan oleh server aplikasi.
-
Dengan permintaan ini, klien web berkomunikasi langsung dengan OSS untuk mengunggah file.
-
Kecuali bidang formulir file, semua bidang formulir lainnya, termasuk key, tidak boleh melebihi 8 KB.
-
Secara default, unggahan berbasis web menimpa objek dengan nama yang sama. Untuk mencegah penimpaan objek, tambahkan bidang formulir x-oss-forbid-overwrite ke permintaan dan atur nilainya ke true. Jika objek dengan nama yang sama sudah ada di OSS, unggahan gagal dan OSS mengembalikan error FileAlreadyExists.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Hasilkan tanda tangan di server untuk mengunggah file ke OSS</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('Silakan 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 objek
formData.append("x-oss-security-token", data.security_token);
formData.append("file", file); // file harus menjadi bidang formulir terakhir
return fetch(data.host, {
method: "POST",
body: formData
});
})
.then((response) => {
if (response.ok) {
console.log("Unggahan berhasil.");
alert("File berhasil diunggah.");
} else {
console.log("Unggahan gagal", response);
alert("Unggahan gagal. Silakan coba lagi nanti.");
}
})
.catch((error) => {
console.error("Terjadi kesalahan:", error);
});
});
});
</script>
</body>
</html>
-
Formulir HTML berisi input file dan tombol submit.
-
Saat formulir dikirim, kode JavaScript mencegah pengiriman default dan mengirim permintaan AJAX ke server aplikasi untuk informasi tanda tangan yang diperlukan.
-
Setelah menerima informasi tanda tangan, kode membuat objek
FormDatadengan bidang formulir yang diperlukan. -
Kemudian, kode tersebut menggunakan metode
fetchuntuk mengirim permintaan POST ke URL OSS guna mengunggah file.
Jika unggahan berhasil, pesan "File berhasil diunggah." ditampilkan. Jika unggahan gagal, pesan error ditampilkan.
Verifikasi
Setelah penerapan, akses server aplikasi Anda untuk menguji fitur unggah langsung dengan URL yang ditandatangani.
-
Di browser, akses server aplikasi Anda. Klik Select File, pilih file, lalu unggah.
-
Di halaman Buckets, buka bucket yang Anda buat dan verifikasi bahwa objek yang diunggah ada.
Konfigurasi yang direkomendasikan
Kebijakan unggah file
Anda dapat memodifikasi kebijakan dalam kode Anda untuk mengatur izin dan batasan unggahan file ke OSS dari formulir HTML. Kebijakan berformat JSON memungkinkan Anda membatasi unggahan dengan mengatur parameter seperti nama bucket yang diizinkan, awalan objek, waktu kedaluwarsa, metode HTTP yang diizinkan, batas ukuran konten, dan tipe konten.
{
"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/jpeg", "image/png"]],
["not-in", "$cache-control", ["no-cache"]]
]
}
Untuk informasi selengkapnya tentang parameter kebijakan, lihat Post Policy.
Penandatanganan sisi server dan callback unggahan
Untuk menerima metadata tentang file yang diunggah, seperti nama file dan ukurannya, konfigurasikan callback unggahan. Setelah file diunggah, OSS mengirim informasi file tersebut ke server aplikasi Anda. Untuk informasi selengkapnya, lihat Server-side signing and direct upload with an upload callback.
Batasi asal CORS
Untuk kesederhanaan, asal yang diizinkan sebelumnya diatur ke karakter wildcard *. Sebagai praktik keamanan terbaik, Anda harus mengganti wildcard tersebut dengan URL spesifik server aplikasi Anda. Hal ini memastikan bahwa hanya permintaan lintas asal dari server Anda yang diotorisasi.
|
Parameter |
Nilai contoh |
|
Origin |
|
|
Allowed Methods |
POST, PUT, GET |
|
Allowed Headers |
* |
Bersihkan sumber daya
Dalam solusi ini, Anda membuat satu instance ECS, satu bucket OSS, satu pengguna RAM, dan satu peran RAM. Setelah selesai menguji, bersihkan sumber daya ini untuk menghindari biaya berkelanjutan atau risiko keamanan.
Lepaskan instance ECS
Jika Anda tidak lagi memerlukan instance tersebut, lepaskan. Setelah melepaskan instance, penagihan berhenti dan Anda tidak dapat memulihkan datanya.
-
Buka halaman Instances di Konsol ECS. Temukan instance ECS target berdasarkan wilayah dan ID instance, lalu klik
di kolom Actions. -
Pilih Release. Di menu yang muncul, klik Release.
-
Konfirmasi detail instance, pilih Release Now, lalu klik Next.
-
Tinjau sumber daya terkait yang akan dilepaskan, akui risiko data terkait, lalu klik Confirm.
-
Disk sistem dan alamat IP publik yang ditetapkan dilepaskan bersama instance.
-
Grup keamanan, vSwitch, dan VPC tidak dilepaskan bersama instance. Sumber daya ini gratis, tetapi Anda dapat menghapusnya jika tidak lagi diperlukan.
-
EIP tidak dilepaskan bersama instance dan terus dikenai biaya. Hapus secara terpisah jika tidak lagi diperlukan.
Hapus bucket OSS
-
Login ke Konsol OSS.
-
Klik Buckets, lalu klik nama bucket OSS target.
-
Hapus semua objek di bucket tersebut.
-
Di panel navigasi sebelah kiri, klik Delete Bucket dan ikuti petunjuk di layar.
Hapus pengguna RAM
-
Login ke Konsol RAM sebagai pengguna RAM dengan hak istimewa admin.
-
Di panel navigasi sebelah kiri, pilih .
-
Di halaman Users, temukan pengguna RAM target dan klik Delete di kolom Actions.
Atau, pilih beberapa pengguna RAM dan klik Delete User di bawah daftar untuk memindahkannya ke Recycle Bin.
-
Di kotak dialog Delete User, tinjau dengan cermat dampak penghapusan, masukkan nama pengguna RAM target, lalu klik Move to Recycle Bin.
Hapus peran RAM
-
Login ke Konsol RAM sebagai pengguna RAM dengan hak istimewa admin.
-
Di panel navigasi sebelah kiri, pilih .
-
Di halaman Roles, temukan peran RAM target dan klik Delete Role di kolom Actions.
-
Di kotak dialog Delete Role, masukkan nama peran RAM dan klik Delete Role.
CatatanJika peran RAM memiliki kebijakan yang dilampirkan, menghapus peran tersebut juga melepas kebijakan tersebut.
FAQ
Unggahan multipart dan yang dapat dilanjutkan
Solusi ini menggunakan unggahan formulir dan tidak mendukung unggahan multipart atau yang dapat dilanjutkan. Untuk menggunakan metode ini, lihat Resumable upload dan Multipart upload.
Cegah penimpaan file
Atur parameter x-oss-forbid-overwrite ke true di bidang formulir unggahan. Contohnya:
formData.append('x-oss-forbid-overwrite', 'true');