Skip to main content
  1. Artikel-artikel/
  2. Framework Javascript/

Svelte Basic Auth Auth 3

·951 words·5 mins· loading · loading · ·
Development Js Framework Svelte Nodejs
Humaedi
Author
Humaedi
Halo, nama saya Humaedi 👋. Saya seorang CEO of Akaktekno.id & { full-stack developer } Bekerjalah seakan hidup abadi, beribadah seakan mau mati, jangan lupa☕️ untuk mendapat inspirasi.
svelte-basic-auth - This article is part of a series.
Part : This Article

Halo para seniman yang budiman! Selamat datang kembali! Pada kesempatan kali ini, kita membuat tiga API utama untuk menangani authentication (Login, Register, dan Logout). Setiap API memiliki fungsinya masing-masing untuk mengelola sesi pengguna dan data yang tersimpan di PostgreSQL. Berikut penjelasan detailnya:

1. API untuk Register
#

Kode untuk register bertugas membuat pengguna baru dengan meng-hash password mereka dan menyimpan data di database.

// src/routes/api/register/+server.ts
import type { RequestHandler } from '@sveltejs/kit';
import bcrypt from 'bcrypt';
import sql from '$lib/server/db';

// Fungsi untuk memeriksa apakah email sudah terdaftar
async function isEmailTaken(email: string): Promise<boolean> {
  const result = await sql`
    SELECT * FROM users WHERE email = ${email}
  `;
  return result.length > 0;
}

// Fungsi untuk membuat pengguna baru
async function createUser(email: string, hashedPassword: string, firstName: string, lastName: string): Promise<void> {
  await sql`
    INSERT INTO users (email, password, first_name, last_name) 
    VALUES (${email}, ${hashedPassword}, ${firstName}, ${lastName})
  `;
}

// Fungsi untuk memvalidasi format email
function isValidEmail(email: string): boolean {
  const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
  return emailRegex.test(email);
}

// Handler untuk menangani permintaan POST (register)
export const POST: RequestHandler = async ({ request }) => {
  try {
    const { email, password, firstName, lastName } = await request.json();

    // Validasi email
    if (!isValidEmail(email)) {
      return new Response(JSON.stringify({ success: false, message: 'Invalid email format' }), {
        status: 400,
        headers: { 'Content-Type': 'application/json' }
      });
    }

    // Cek apakah email sudah digunakan
    if (await isEmailTaken(email)) {
      return new Response(JSON.stringify({ success: false, message: 'Email is already taken' }), {
        status: 400,
        headers: { 'Content-Type': 'application/json' }
      });
    }

    // Hash password
    const hashedPassword = await bcrypt.hash(password, 10);

    // Simpan pengguna baru di database
    await createUser(email, hashedPassword, firstName, lastName);

    return new Response(JSON.stringify({ success: true, message: 'User registered successfully' }), {
      status: 201,
      headers: { 'Content-Type': 'application/json' }
    });
  } catch (error) {
    return new Response(JSON.stringify({ success: false, message: `Internal server error: ${error}` }), {
      status: 500,
      headers: { 'Content-Type': 'application/json' }
    });
  }
};

Penjelasan Kode:

  • isEmailTaken: Memeriksa apakah email sudah terdaftar di database.
  • createUser: Menyimpan data pengguna baru dengan hashed password.
  • isValidEmail: Validasi format email menggunakan regex.

2. API untuk Login
#

Kode untuk login bertanggung jawab memverifikasi kredensial pengguna (email dan password), membuat sesi baru, dan menyimpan token sesi ke dalam cookie pengguna.

// src/routes/api/login/+server.ts
import bcrypt from 'bcrypt';
import { randomUUID } from 'crypto'; // Untuk membuat token sesi
import type { RequestHandler } from '@sveltejs/kit';
import sql from '$lib/server/db'; // Koneksi database PostgreSQL

// Fungsi untuk mendapatkan pengguna berdasarkan email
async function getUserByEmail(email: string) {
  const result = await sql`
    SELECT * FROM users WHERE email = ${email}
  `;
  return result[0];
}

// Fungsi untuk membuat sesi baru
async function createSession(user_id: number, token: string) {
  await sql`
    INSERT INTO sessions (user_id, token, expires_at)
    VALUES (${user_id}, ${token}, NOW() + INTERVAL '1 day')
  `;
}

// Handler untuk menangani permintaan POST (login)
export const POST: RequestHandler = async ({ request, cookies }) => {
  const { email, password }: { email: string; password: string } = await request.json();

  // Cari pengguna berdasarkan email
  const user = await getUserByEmail(email);
  if (user) {
    // Verifikasi password
    const passwordMatch = await bcrypt.compare(password, user.password);
    if (passwordMatch) {
      // Jika password cocok, buat sesi baru
      const sessionToken = randomUUID();
      await createSession(user.id, sessionToken);
      
      // Set token sesi ke dalam cookie
      cookies.set('session', sessionToken, {
        path: '/',
        httpOnly: true,
        secure: process.env.NODE_ENV === 'production', // Amankan cookie di production
        maxAge: 60 * 60 * 24 // Kadaluarsa dalam 1 hari
      });

      return new Response(JSON.stringify({ success: true, message: 'Login successful' }), {
        status: 200,
        headers: { 'Content-Type': 'application/json' }
      });
    } else {
      // Jika password salah
      return new Response(JSON.stringify({ success: false, message: 'Invalid password' }), {
        status: 401,
        headers: { 'Content-Type': 'application/json' }
      });
    }
  } else {
    // Jika email tidak ditemukan
    return new Response(JSON.stringify({ success: false, message: 'Invalid email' }), {
      status: 401,
      headers: { 'Content-Type': 'application/json' }
    });
  }
};

Penjelasan Kode:

  • getUserByEmail: Mencari pengguna di database berdasarkan email yang diinputkan.
  • createSession: Membuat token sesi unik menggunakan randomUUID() dan menyimpannya di tabel sessions.
  • Cookie session diset untuk menyimpan token sesi pada pengguna selama 1 hari (maxAge: 60 * 60 * 24).

3. API untuk Logout
#

Kode untuk logout bertugas menghapus sesi pengguna dari database dan menghapus cookie sesi dari browser pengguna.

// src/routes/api/logout/+server.ts
import type { RequestHandler } from '@sveltejs/kit';
import sql from '$lib/server/db';

// Fungsi untuk menghapus sesi berdasarkan token
async function deleteSessionByToken(token: string) {
  await sql`
    DELETE FROM sessions WHERE token = ${token}
  `;
}

// Handler untuk menangani permintaan POST (logout)
export const POST: RequestHandler = async ({ cookies }) => {
  const sessionToken = cookies.get('session');

  if (sessionToken) {
    await deleteSessionByToken(sessionToken); // Hapus sesi dari database
  }

  // Hapus cookie sesi
  cookies.set('session', '', {
    path: '/',
    httpOnly: true,
    maxAge: 0 // Hapus cookie segera
  });

  return new Response(null, {
    status: 302,
    headers: {
      Location: '/login' // Redirect pengguna ke halaman login
    }
  });
};

Penjelasan Kode:

  • deleteSessionByToken: Menghapus sesi pengguna dari tabel sessions berdasarkan token sesi.
  • Cookie session dihapus dengan maxAge: 0, yang mengakibatkan penghapusan segera.
  • Setelah logout berhasil, pengguna di-redirect ke halaman login (/login).

Penjelasan:
#

  1. Login API (/api/login):

    • Menerima permintaan POST dengan email dan password.
    • Memeriksa apakah pengguna ada di database.
    • Memverifikasi password yang diberikan dengan password yang tersimpan menggunakan bcrypt.
    • Jika verifikasi berhasil, memberikan respons sukses; jika tidak, memberikan pesan kesalahan.
  2. Register API (/api/register):

    • Menerima permintaan POST dengan username, email, dan password.
    • Meng-hash password menggunakan bcrypt untuk keamanan.
    • Menyimpan pengguna baru ke dalam database.
    • Memberikan respons sukses jika registrasi berhasil.
  3. Logout API (/api/logout):

    • Pada logout, biasanya Anda dapat menghapus sesi pengguna atau token autentikasi (seperti token di cookie).
    • Dalam contoh ini, kita mengirim respons bahwa pengguna berhasil logout.

Dengan API ini, aplikasi Svelte Anda sudah memiliki fitur authentication dasar yang bisa dihubungkan dengan halaman frontend.

svelte-basic-auth - This article is part of a series.
Part : This Article

Related

Svelte Basic Auth Auth 2
·858 words·5 mins· loading · loading
Development Js Framework Svelte Nodejs
Halo para seniman yang budiman!
Svelte Basic Auth Auth 1
·870 words·5 mins· loading · loading
Development Js Framework Svelte Nodejs
Halo para seniman yang budiman!
Tutorial Laravel 11 Sharing Auth 2
·470 words·3 mins· loading · loading
Development Php Framework Laravel
Halo para seniman yang budiman!