Operasi PostObject memungkinkan Anda mengunggah file langsung dari klien web ke Object Storage Service (OSS). Operasi ini menggunakan signature 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 temporary 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) agar bucket mengizinkan permintaan lintas asal dari klien web.
Konfigurasikan server: Panggil Security Token Service (STS) untuk mendapatkan kredensial akses temporary, lalu gunakan kredensial tersebut beserta kebijakan unggah sisi server untuk menghasilkan signature. Kebijakan ini mencakup parameter seperti nama bucket, path direktori, dan waktu kedaluwarsa. Signature ini memberi otorisasi kepada pengguna untuk mengunggah file dalam periode tertentu.
Konfigurasikan klien web: Susun permintaan formulir HTML dan gunakan signature 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.
Pada panel navigasi kiri, klik Buckets, lalu klik Create Bucket.
Pada 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.
Pada halaman Buckets, klik bucket target.
Pada halaman CORS, klik Create Rule.
Pada 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 menuju 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.
Pada 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.Konfigurasi vSwitch contoh: 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 tidak diperlukan disk data.
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. Alternatifnya, Anda dapat mengaitkan Elastic IP Address (EIP) ke instans setelah membuatnya. Untuk informasi selengkapnya, lihat Mengaitkan EIP dengan sumber daya cloud.
CatatanJika Alamat IP publik tidak ditetapkan, Anda tidak dapat menggunakan SSH atau Remote Desktop Protocol (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 Penagihan bandwidth publik.
Atur Peak bandwidth ke 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).
CatatanPort yang dipilih untuk Port range diperlukan oleh aplikasi yang berjalan pada instance ECS.
Secara default, grup keamanan yang dibuat di sini mencakup aturan yang menetapkan source 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 merekomendasikan agar Anda kemudian membatasi source ke rentang IP tertentu. Untuk informasi selengkapnya, lihat Memodifikasi aturan grup keamanan.
Pada 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 merekomendasikan agar Anda menggunakanecs-usersebagai nama login.CatatanSetelah membuat pasangan kunci, kunci privat akan diunduh secara otomatis. Simpan file kunci privat
.pemdari riwayat unduhan browser Anda.Pada 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 dalam daftar instance.
Region: Digunakan untuk menemukan instance dalam daftar instance.
Public IP address: Digunakan untuk memverifikasi penerapan layanan web.
Langkah 2: Hubungkan ke instance ECS
Pada halaman Instances di Konsol ECS, temukan instance Anda menggunakan wilayah dan ID-nya, lalu pada kolom Actions, klik Connect.
Pada kotak dialog Remote connection, klik Sign in now di sebelah Workbench.
Pada 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 berfungsi sebagai kredensial jangka panjang bagi server aplikasi Anda.
Login ke Konsol RAM dengan Akun Alibaba Cloud Anda atau sebagai administrator RAM.
Pada panel navigasi kiri, pilih Identities > Users.
Klik Create User.
Masukkan Logon Name dan Display Name.
Pada bagian Access Mode, pilih Programmatic access, lalu klik OK.
Rahasia AccessKey hanya ditampilkan saat pembuatan dan tidak dapat diambil kembali nanti. Simpan dengan aman.
Pada 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 temporary dengan mengasumsikan peran RAM.
Pada panel navigasi kiri, pilih Identities > Users.
Pada halaman Users, temukan pengguna RAM target, lalu klik Add Permissions di kolom Actions.
Pada 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 temporary, 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.
Pada panel navigasi 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.
Pada 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.
Pada panel navigasi kiri, pilih Permissions > Policies.
Klik Create Policy.
Pada 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.
Pada kotak dialog Create Policy, masukkan Policy Name dan klik OK.
Langkah 5: Berikan izin ke peran RAM
Berikan Kebijakan Kustom yang Anda buat ke peran RAM. Hal ini memberikan izin yang diperlukan kepada peran yang diasumsikan.
Pada panel navigasi kiri, pilih Identities > Roles.
Pada halaman Roles, temukan peran RAM target, lalu klik Add Permissions di kolom Actions.
Pada halaman Grant Permission, pilih Custom Policy, lalu pilih kebijakan yang Anda buat.
Klik OK.
Signature sisi server
Kami merekomendasikan 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 menetapkan 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'" >> ~/.bashrcJalankan perintah berikut untuk menerapkan perubahan.
source ~/.bashrcJalankan perintah berikut untuk memverifikasi bahwa variabel lingkungan telah ditetapkan.
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 $SHELLIkuti 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'" >> ~/.zshrcJalankan perintah berikut untuk menerapkan perubahan.
source ~/.zshrcJalankan perintah berikut untuk memverifikasi bahwa variabel lingkungan telah ditetapkan.
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_profileJalankan perintah berikut untuk menerapkan perubahan.
source ~/.bash_profileJalankan perintah berikut untuk memverifikasi bahwa variabel lingkungan telah ditetapkan.
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 ditetapkan.
echo %OSS_ACCESS_KEY_ID% echo %OSS_ACCESS_KEY_SECRET% echo %OSS_STS_ROLE_ARN%
Gunakan kode contoh berikut untuk menghitung signature POST di server dengan Signature Version 4 (direkomendasikan). Untuk informasi selengkapnya tentang mengonfigurasi field form policy, lihat field form policy.
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 temporary dan menghitung signature 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";
// Tetapkan 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 AccessKey merupakan risiko keamanan dan tidak direkomendasikan. 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 ditetapkan di lingkungan runtime kode Anda.
.setAccessKeyId(System.getenv("OSS_ACCESS_KEY_ID"))
// Wajib. Pastikan variabel lingkungan OSS_ACCESS_KEY_SECRET ditetapkan di lingkungan runtime kode Anda.
.setAccessKeySecret(System.getenv("OSS_ACCESS_KEY_SECRET"));
// Untuk informasi selengkapnya tentang endpoint, lihat https://api.alibabacloud.com/product/Sts.
config.endpoint = "sts.cn-hangzhou.aliyuncs.com";
return new com.aliyun.sts20150401.Client(config);
}
/**
* Dapatkan kredensial temporary 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 ditetapkan 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 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 signature.
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 signature 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_credentialsKode contoh berikut menunjukkan cara mendapatkan kredensial akses temporary (token STS), menyusun kebijakan unggahan, dan menghitung signature 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 ke 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 buat 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 expressKode contoh berikut menunjukkan cara mendapatkan kredensial akses temporary (token STS), menyusun kebijakan unggahan, dan menghitung signature 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.
// Tetapkan 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 temporary.
const result = await sts.assumeRole(process.env.OSS_STS_ROLE_ARN, '', '3600', 'yourRoleSessionName'); // Dapatkan ARN peran RAM dari variabel lingkungan. Kredensial akses temporary berlaku selama 3.600 detik, dan nama sesi peran adalah nilai kustom, seperti yourRoleSessionName.
// Ekstrak AccessKeyId, AccessKeySecret, dan SecurityToken dari kredensial akses temporary.
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 form.
const formData = new Map();
// Tetapkan waktu kedaluwarsa signature ke 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 tetapkan data form.
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 form.
if (client.options.stsToken) {
policy.conditions.push({ 'x-oss-security-token': client.options.stsToken });
formData.set('security_token', client.options.stsToken);
}
// Hasilkan signature dan tetapkan data form.
const signature = client.signPostObjectPolicyV4(policy, date);
formData.set('policy', Buffer.from(policy2Str(policy), 'utf8').toString('base64'));
formData.set('signature', signature);
// Kembalikan data form.
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 signature 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 tidyKode contoh berikut menunjukkan cara mendapatkan kredensial akses temporary (token STS), menyusun kebijakan unggahan, dan menghitung signature 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"
)
// Struct PolicyToken menyimpan data form 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 path root.
http.HandleFunc("/", handlerRequest)
// Daftarkan fungsi untuk menangani permintaan pembuatan signature.
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 path 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 signature.
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 signature dan kredensial yang diperlukan untuk unggahan OSS.
func getPolicyToken() string {
// Tetapkan wilayah bucket.
region = "cn-hangzhou"
// Ganti dengan nama bucket Anda.
bucketName = "examplebucket"
// Tetapkan alamat unggahan OSS.
host := fmt.Sprintf("https://%s.oss-%s.aliyuncs.com", bucketName, region)
// Tetapkan 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 untuk 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 signature.
h := hmac.New(hmacHash, h4Key)
io.WriteString(h, stringToSign)
signature := hex.EncodeToString(h.Sum(nil))
// Susun form 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 installKode contoh berikut menunjukkan cara mendapatkan kredensial akses temporary (token STS), menyusun kebijakan unggahan, dan menghitung signature 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 signature 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();
// Lakukan permintaan STS dan dapatkan hasilnya.
// Tetapkan <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 untuk 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 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 signature.
$result = hmacsha256($signingKey, $stringToSign);
$signature = bin2hex($result);
// Kembalikan data signature.
$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 form 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 field 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 form berbasis browser. Untuk informasi selengkapnya, lihat Post Policy. |
security_token | Kredensial temporary yang digunakan untuk otentikasi, disediakan oleh STS. |
signature | Signature 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 signature. Nilainya tetap OSS4-HMAC-SHA256. |
Permintaan form mencakup konten file dan parameter yang dikembalikan oleh server aplikasi.
Dengan permintaan ini, klien web berkomunikasi langsung dengan OSS untuk mengunggah file.
Kecuali field form file, semua field form lainnya, termasuk key, tidak boleh melebihi 8 KB.
Secara default, unggahan berbasis web menimpa objek dengan nama yang sama. Untuk mencegah objek ditimpa, tambahkan field form 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 signature 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 signature");
}
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 field form 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 signature yang diperlukan.
Setelah menerima informasi signature, kode tersebut membuat objek
FormDatadengan field form yang diperlukan.Kemudian, kode tersebut menggunakan metode
fetchuntuk mengirim permintaan POST ke URL OSS untuk 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 menetapkan izin dan batasan unggahan file ke OSS dari formulir HTML. Kebijakan berformat JSON memungkinkan Anda membatasi unggahan dengan menetapkan 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 Penandatanganan sisi server dan unggah langsung dengan callback unggahan.
Batasi origin CORS
Untuk kesederhanaan, origin 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 dalam bucket.
Di panel navigasi kiri, klik Delete Bucket dan ikuti petunjuk di layar.
Hapus pengguna RAM
Login ke Konsol RAM sebagai pengguna RAM dengan hak admin.
Di panel navigasi 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 admin.
Di panel navigasi 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 form dan tidak mendukung unggahan multipart atau yang dapat dilanjutkan. Untuk menggunakan metode ini, lihat Unggah yang dapat dilanjutkan dan Unggahan multipart.
Cegah penimpaan file
Tetapkan parameter x-oss-forbid-overwrite ke true di field form unggahan. Contohnya:
formData.append('x-oss-forbid-overwrite', 'true');