Praktik Secure Coding (Part 2): Membuat REST API Kebal Injeksi di Next.js & Prisma
Halo para penggiat keamanan web! Pada artikel Part 1 sebelumnya, kita telah berhasil melakukan instalasi dan merancang fondasi arsitektur Full-Stack menggunakan Next.js dan Prisma ORM. Lingkungan kerja kita kini sudah aman dan siap digunakan.
Langkah krusial selanjutnya dalam membangun sebuah Learning Management System (LMS) atau web edukasi matematika adalah membuat REST API. API (Application Programming Interface) adalah "jembatan" pengantar data antara database dan tampilan pengguna (Frontend).
Sayangnya, dalam laporan OWASP Top 10, celah pada API (seperti Broken Object Level Authorization dan Injection) sering kali menjadi pintu masuk utama para peretas. Oleh karena itu, di Part 2 ini, kita akan mempraktikkan cara membuat REST API yang aman dari manipulasi data, menggunakan tabel grades (Kelas) dari database yang sudah ada.
Tips Pro: Menarik Database Lama Tanpa Ketik Manual
Jika Anda sudah memiliki database MySQL lama (misalnya dari proyek PHP/CodeIgniter), Anda tidak perlu mengetik ulang strukturnya di Prisma! Gunakan perintah ajaib ini di terminal:
npx prisma db pull
npx prisma generate
Prisma akan melakukan Introspection dan menyedot seluruh tabel (seperti tabel kelas, materi, dan kuis) langsung ke dalam file schema.prisma Anda secara otomatis. Sangat menghemat waktu!
Aturan Emas Keamanan API: "Jangan Pernah Percaya Input Pengguna"
Kesalahan terbesar developer pemula adalah langsung memasukkan data yang dikirim oleh pengguna (dari form input) ke dalam database. Di Next.js dipadukan dengan Prisma, kita memiliki sistem perlindungan ganda.
Mari kita buat sebuah API untuk menambahkan data (Create) Kelas baru secara aman.
1. Membuat Route POST di Next.js
Buka proyek VS Code Anda, buat struktur folder app/api/kelas, dan buat file baru bernama route.ts. Kita akan menyusun fungsi GET dan POST di dalamnya.
Tambahkan kode berikut ini:
import { NextResponse } from 'next/server';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
// Fungsi GET: Mengambil data kelas
export async function GET() {
try {
const dataKelas = await prisma.grades.findMany({
orderBy: { sort_order: 'asc' }
});
return NextResponse.json({ status: 'success', data: dataKelas });
} catch (error) {
return NextResponse.json({ status: 'error', message: 'Internal Server Error' }, { status: 500 });
}
}
// Fungsi POST: Menambahkan Data Baru dengan Aman
export async function POST(request: Request) {
try {
// 1. Menangkap data dari request body (Frontend)
const body = await request.json();
const { name, sort_order } = body;
// 2. Validasi Lapis Pertama (Mencegah Payload Kosong/Berbahaya)
if (!name) {
return NextResponse.json(
{ status: 'error', message: 'Nama kelas wajib diisi!' },
{ status: 400 } // Bad Request
);
}
// 3. Eksekusi ke Database via Prisma (Otomatis Sanitasi SQL Injection)
const kelasBaru = await prisma.grades.create({
data: {
name: name,
sort_order: sort_order || 0,
},
});
// 4. Mencegah Error Serialisasi JSON pada tipe data BigInt
const dataAman = {
...kelasBaru,
id: kelasBaru.id.toString(),
};
// 5. Mengembalikan respon sukses
return NextResponse.json({
status: 'success',
message: 'Kelas berhasil ditambahkan dengan aman!',
data: dataAman
}, { status: 201 }); // Created
} catch (error) {
console.error("API Error:", error);
return NextResponse.json(
{ status: 'error', message: 'Gagal menambahkan data. Terjadi kesalahan server.' },
{ status: 500 }
);
}
}
Membedah Lapisan Keamanan pada Kode di Atas
Jika Anda perhatikan, kode API tersebut tidak hanya sekadar berfungsi, tetapi dirancang dengan prinsip Defensive Programming:
- Validasi Input (Poin 2): Kita mengecek apakah variabel
namebenar-benar ada. Jika peretas mencoba mengirim payload kosong untuk membuat server crash, sistem akan menolaknya dengan status400 Bad Request. - Sanitasi Prisma (Poin 3): Anda tidak melihat adanya perintah
INSERT INTO...bukan? Denganprisma.grades.create, semua input yang mengandung karakter berbahaya akan dinetralkan secara otomatis (Escaping). - Penanganan BigInt (Poin 4): Pada database skala besar (seperti LMS), ID sering kali menggunakan format
BIGINT. Format standar JSON akan crash jika dipaksa membaca BigInt. Mengubahnya menjadi string.toString()adalah langkah pengamanan agar server tidak memunculkan error 500. - Manajemen Error (Try-Catch): Jika terjadi kegagalan (misalnya nama kelas sudah ada / Unique constraint failed), blok
catchakan menyembunyikan detail log dari peretas dan hanya menampilkan pesan umum untuk mencegah Information Disclosure.
Cara Menguji API dengan Aman (Menggunakan Thunder Client)
Karena fungsi POST tidak bisa dijalankan hanya dengan mengetik URL di browser, kita membutuhkan alat khusus (API Client) seperti ekstensi Thunder Client di VS Code.
- Buka Thunder Client di VS Code Anda.
- Buat New Request, ubah metode dari GET menjadi POST.
- Masukkan URL lokal Anda:
http://localhost:3000/api/kelas. - Masuk ke tab Body, pilih JSON, lalu masukkan data pengujian berikut:
{
"name": "Kelas 14",
"sort_order": 3
}
Klik Send. Jika berhasil, Anda akan mendapatkan respon sukses dengan status 201 Created berwarna hijau. Data tersebut secara otomatis sudah masuk ke dalam database MySQL lokal Anda!
Kesimpulan
Membangun REST API yang aman adalah kunci utama dalam arsitektur aplikasi modern. Dengan Next.js App Router dan Prisma ORM, kita bisa memangkas ribuan baris kode validasi manual, mengelola tipe data kompleks secara elegan, sekaligus memastikan sistem kebal terhadap manipulasi tingkat dasar.
Pada artikel Part 3 selanjutnya, kita akan mulai merajut tampilan antarmuka (Frontend) untuk menampilkan data ini agar bisa digunakan secara interaktif oleh pengguna. Jangan lupa bookmark blog ini agar tidak ketinggalan kelanjutannya!


0 Response to "Praktik Secure Coding (Part 2): Membuat REST API Kebal Injeksi di Next.js & Prisma"
Posting Komentar