API, Autentikasi, dan Keamanan · 2/7
Validasi di batas kepercayaan
Apa pun yang bisa dikirim pengguna, bisa dipalsukan pengguna. Di mana memeriksanya, dan apa yang dilakukan saat gagal.
Baca 30 menit
Setelah pelajaran ini kamu bisa
- Menyebutkan di mana tepatnya batas kepercayaan itu
- Memvalidasi bentuk, type, dan aturan bisnis secara terpisah
- Menjelaskan dan mencegah mass assignment
- Memakai library skema alih-alih pemeriksaan manual
Batas kepercayaan adalah titik mana pun di mana data datang dari tempat yang tidak kamu kendalikan. Semua yang menyeberanginya bersifat bermusuhan sampai terbukti sebaliknya — bukan karena penggunamu penyerang, tapi karena kamu tidak bisa membedakannya.
| Sumber | Dipercaya? |
|---|---|
| Kiriman form | Tidak |
| Parameter URL atau query string | Tidak |
| Body request JSON | Tidak |
| Isi sebuah cookie | Tidak — penggunanya bisa mengeditnya |
| Argument Server Action | Tidak — bisa dijangkau lewat POST langsung |
| Response API pihak ketiga | Tidak — mereka berubah tanpa memberitahumu |
| Body webhook | Tidak — sampai signature-nya terverifikasi |
| Database milikmu sendiri | Sebagian besar — kualitasnya sebatas apa yang kamu izinkan masuk |
Validasi punya tiga tugas berbeda, dan mencampuradukkannya adalah sebab kode validasi jadi berantakan.
- Bentuk — apakah ini object dengan field yang saya harapkan, dan tidak lebih?
- Type dan rentang — apakah
nightsbilangan bulat antara 1 dan 30? - Aturan bisnis — apakah venue-nya benar-benar kosong di tanggal itu? Ini butuh database, jadi ia datang terakhir.
Mass assignment
Ini celah yang muncul dari memercayai *bentuk* sebuah payload. Kamu mengambil seluruh body-nya lalu menyerahkannya ke database-mu, dan penyerangnya menyertakan field yang tidak pernah kamu maksudkan bisa mereka atur.
Satu field tambahan di body request. Lihat apa yang dicapainya terhadap masing-masing versi.
Hasil
Tekan Jalankan untuk melihat hasilnya.
Ini jalan di browser kamu, di dalam sandbox. Apa pun yang kamu tulis di sini tidak bisa merusak situs.
Library skema
Pemeriksaan manual memang bekerja — validateCredentials di proyek ini tiga puluh baris untuk dua field — tapi ia sulit diperbesar dan bisa menyimpang dari type-mu. Library skema memvalidasi sekaligus menghasilkan type TypeScript dari satu definisi.
import { z } from "zod";
const BookingSchema = z.object({
venueId: z.number().int().positive(),
guest: z.string().trim().min(2).max(60),
nights: z.number().int().min(1).max(30),
email: z.string().email(),
notes: z.string().max(500).optional(),
});
// The type is DERIVED from the schema - they cannot drift apart.
type Booking = z.infer<typeof BookingSchema>;
export async function createBooking(formData: FormData) {
const result = BookingSchema.safeParse({
venueId: Number(formData.get("venueId")),
guest: formData.get("guest"),
nights: Number(formData.get("nights")),
email: formData.get("email"),
});
if (!result.success) {
// Per-field messages, in the shape the form already expects.
return { error: "validation_failed", fields: result.error.flatten().fieldErrors };
}
// result.data is fully typed AND checked. Unknown keys are stripped.
await insertBooking(result.data);
}safeParse mengembalikan sebuah hasil alih-alih melempar, jadi jalur error-nya eksplisit. Perhatikan key yang tidak dikenal dibuang secara default — perlindungan mass assignment, gratis.Tugas praktik
Tulis ulang validateCredentials di proyek ini memakai zod, dengan mempertahankan key error yang sama supaya dictionary-nya tetap bekerja. Jalankan bun run test validate untuk memastikan setiap test yang ada tetap lolos — test-nya adalah spesifikasinya, dan seharusnya tidak perlu diubah.
Hasil yang diharapkan
Semua test validasi yang ada lolos terhadap implementasi baru.