ASP.NET Core API #12: Membuat Fitur Login dengan Hashing Password (BCrypt) Tanpa JWT

ASP.NET Core API #12: Membuat Fitur Login dengan Hashing Password (BCrypt) Tanpa JWT

Halo lagi, calon developer API yang sadar keamanan! 

Di artikel sebelumnya (#11) kita membuat login dengan password plain text — itu ibarat menyimpan kunci rumah di bawah keset, sangat tidak aman! Sekarang kita akan meningkatkan keamanan dengan meng-hash password menggunakan BCrypt. Password akan disimpan dalam bentuk terenkripsi (hash) sehingga meskipun database bocor, password asli tidak langsung diketahui. Tapi kita masih belum menggunakan JWT; kita hanya akan mengembalikan pesan sukses. Fokus di sini adalah penyimpanan password yang aman.

🤣 Kenapa BCrypt disebut BCrypt? Karena dia bikin password Berubah jadi Crypt (kriptik) susah ditebak! 😆

Apa yang Akan Kita Buat?

  • Mengubah model User: kolom Password akan menyimpan hash, bukan plain text.
  • Menginstal package BCrypt.Net-Next untuk hashing.
  • Memodifikasi endpoint register agar meng-hash password sebelum disimpan.
  • Memodifikasi endpoint login agar memverifikasi password dengan hash yang tersimpan.
  • Data user yang sudah ada (plain text) perlu di-update atau buat baru.
  • Uji coba dengan Postman.

Langkah 1: Install Package BCrypt

Buka Package Manager Console (Tools → NuGet Package Manager → Package Manager Console). Jalankan perintah:

Install-Package BCrypt.Net-Next

Atau jika menggunakan .NET CLI:

dotnet add package BCrypt.Net-Next

Package ini menyediakan fungsi BCrypt.HashPassword() dan BCrypt.Verify().

Langkah 2: Update Model User (Tidak Ada Perubahan Struktural)

Secara struktural, model User tetap sama karena kita tetap menyimpan string di kolom Password. Bedanya, string tersebut sekarang akan berisi hash, bukan plain text. Jadi tidak perlu migration baru. Tapi kita perlu memperbarui data user yang ada.

⚠️ Data user lama (plain text) harus diperbarui atau dihapus karena tidak bisa diverifikasi dengan BCrypt (hash berbeda). Kita bisa tambahkan user baru dengan password ter-hash.

Langkah 3: Modifikasi Endpoint Register

Buka AuthController.cs. Ubah method Register menjadi:

[HttpPost("register")]
public async Task<IActionResult> Register(RegisterDto registerDto)
{
    // Cek apakah username sudah ada
    if (await _context.Users.AnyAsync(u => u.Username == registerDto.Username))
    {
        return BadRequest(new { message = "Username sudah digunakan." });
    }

    // Hash password sebelum disimpan
    string passwordHash = BCrypt.Net.BCrypt.HashPassword(registerDto.Password);

    var user = new User
    {
        Username = registerDto.Username,
        Password = passwordHash // simpan hash, bukan plain text
    };

    _context.Users.Add(user);
    await _context.SaveChangesAsync();

    return Ok(new { message = "Registrasi berhasil." });
}

Penjelasan: BCrypt.HashPassword() menghasilkan string hash yang sudah termasuk salt secara otomatis. Jadi kita tidak perlu menyimpan salt terpisah.

Langkah 4: Modifikasi Endpoint Login

Ubah method Login menjadi:

[HttpPost("login")]
public async Task<IActionResult> Login(LoginDto loginDto)
{
    // Cari user berdasarkan username
    var user = await _context.Users
        .FirstOrDefaultAsync(u => u.Username == loginDto.Username);

    if (user == null)
    {
        return Unauthorized(new { message = "Username atau password salah." });
    }

    // Verifikasi password yang dikirim dengan hash di database
    bool isValid = BCrypt.Net.BCrypt.Verify(loginDto.Password, user.Password);

    if (!isValid)
    {
        return Unauthorized(new { message = "Username atau password salah." });
    }

    // Login sukses (tanpa token)
    var response = new LoginResponseDto
    {
        Id = user.Id,
        Username = user.Username,
        Message = "Login berhasil."
    };

    return Ok(response);
}

BCrypt.Verify() akan membandingkan password plain text dengan hash, mengembalikan true jika cocok.

Langkah 5: Membersihkan Data Lama (Opsional)

Jika sudah ada data user dengan plain text, kita perlu menghapusnya atau memperbaruinya dengan hash. Bisa melalui SQL atau buat migration data. Untuk sementara, kita hapus saja data lama dan daftar ulang.

Di SSMS, jalankan:

DELETE FROM Users;

Atau jika ingin mempertahankan, kita bisa update manual dengan hash, tapi repot. Lebih baik daftar ulang.

Langkah 6: Uji Coba dengan Postman

Jalankan API (F5). Buka Postman.

1. Registrasi User Baru

  • Method: POST
  • URL: https://localhost:7000/api/auth/register
  • Body (raw JSON):
{
    "username": "joko",
    "password": "rahasia123"
}

Response: { "message": "Registrasi berhasil." }

2. Cek Database

Lihat tabel Users, kolom Password akan berisi string panjang seperti $2a$11$... . Itu adalah hash BCrypt.

3. Login dengan password benar

  • Method: POST
  • URL: https://localhost:7000/api/auth/login
  • Body:
{
    "username": "joko",
    "password": "rahasia123"
}

Response sukses:

{
    "id": 1,
    "username": "joko",
    "message": "Login berhasil."
}

4. Login dengan password salah

{
    "username": "joko",
    "password": "salah"
}

Response 401 Unauthorized.

⚡ Keuntungan Menggunakan BCrypt

  • Salt otomatis: Setiap hash unik meskipun password sama.
  • Lambat secara sengaja: Mempersulit serangan brute force.
  • Adaptif: Bisa ditingkatkan kekuatan hash-nya seiring waktu.

Bagaimana Cara Kerja BCrypt?

BCrypt menghasilkan hash dengan format: $2a$[cost]$[salt][hash]. Cost menentukan seberapa lambat proses hashing (default 10-12). Saat verifikasi, BCrypt membaca cost dan salt dari hash, lalu menghitung ulang dan membandingkan. Sangat praktis!

💡 Karena BCrypt sudah menyimpan salt di dalam hash, kita tidak perlu kolom terpisah untuk salt. Praktis kan?

Masih Tanpa JWT, Tapi Lebih Aman

Sekarang password tersimpan aman, tapi kita masih belum menggunakan JWT. Artinya setelah login, kita tidak memberi token ke client. Client harus mengirim username/password lagi setiap kali akses endpoint yang dilindungi — ini tidak praktis dan tidak aman. Di sinilah JWT berperan. Tapi untuk pembelajaran, kita fokus dulu pada hashing.

Di artikel #7 dan #8 kita sudah membahas JWT. Kamu bisa menggabungkan hashing BCrypt dengan JWT untuk keamanan maksimal.

Selamat! Password Kamu Sekarang Tersimpan Aman

Dengan BCrypt, password user tidak lagi terlihat meskipun database bocor. Ini langkah penting menuju aplikasi yang profesional.

📌 Rangkuman

  • BCrypt meng-hash password dengan salt otomatis.
  • Gunakan BCrypt.HashPassword() saat registrasi.
  • Gunakan BCrypt.Verify() saat login.
  • Data user lama harus diperbarui karena hash berbeda.

Selanjutnya?

Kamu sekarang sudah memahami autentikasi dasar dan hashing. Untuk produksi, kombinasikan dengan JWT (lihat artikel #7 dan #8). Kamu juga bisa membuat endpoint logout, refresh token, dll.

Terima kasih telah mengikuti seri API ini. Semoga bermanfaat!

😎 Sekarang passwordmu sudah aman kayak dititipin ke penjara bawah tanah. Tapi jangan lupa, yang jagain (server) juga harus aman ya!

Ditulis oleh Kakak programmer yang dulu juga pakai plain text, lalu tobat setelah kena bobol. Kalau ada pertanyaan, tulis di komentar ya!

📋 DAFTAR ISI LENGKAP SERI ASP.NET CORE API
🔹 ASP.NET Core API #1: Persiapan Lingkungan dan Instalasi Tools 🔹 ASP.NET Core API #2: Membuat Project API Pertama dan Menampilkan Hello World 🔹 ASP.NET Core API #3: Mendesain Database Wisata – Tabel Kategori dan Daftar Wisata 🔹 ASP.NET Core API #4: Menghubungkan API dengan Database Menggunakan Entity Framework Core 🔹 ASP.NET Core API #5: Membuat CRUD untuk Kategori Wisata (GET, POST, PUT, DELETE) 🔹 ASP.NET Core API #6: Membuat CRUD untuk Daftar Wisata dengan Relasi Kategori 🔹 ASP.NET Core API #7: Menambahkan Fitur Login dan Registrasi dengan JWT 🔹 ASP.NET Core API #8: Mengamankan Endpoint API Menggunakan Token JWT 🔹 ASP.NET Core API #9: (Bonus) Upload Gambar untuk Daftar Wisata 🔹 ASP.NET Core API #10: Deployment API ke IIS atau Azure 🔹 ASP.NET Core API #11: Membuat Fitur Login Sederhana (Tanpa JWT dan Tanpa Hashing) 🔹 ASP.NET Core API #12: Membuat Fitur Login dengan Hashing Password (BCrypt) Tanpa JWT
✨ Klik judul untuk membaca artikel
Lebih baru Lebih lama

نموذج الاتصال