Membuat Sistem Login dengan Node.js dan MySQL - Perwira Learning Center

 

1. Latar Belakang

Autentikasi (login & register) adalah fitur penting dalam aplikasi. Dengan MySQL, data user disimpan dalam bentuk tabel terstruktur. Kita tetap akan menggunakan:

  • bcrypt → hashing password

  • jsonwebtoken (JWT) → token login


2. Alat dan Bahan

Install dependency :

 npm init -y
npm install express mysql2 bcryptjs jsonwebtoken
npm install nodemon --save-dev


3. Pembahasan 

    3.1 Membuat Database dan Tabel

Masuk ke MySQL server :

 CREATE DATABASE dbauth;
USE dbauth;

CREATE TABLE users (
  id INT AUTO_INCREMENT PRIMARY KEY,
  nama VARCHAR(100) NOT NULL,
  email VARCHAR(100) NOT NULL UNIQUE,
  password VARCHAR(255) NOT NULL
);


    3.2 Setup Server dan Koneksi Database

Buat file index.js :

 const express = require("express");
const mysql = require("mysql2");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");

const app = express();
app.use(express.json());

const db = mysql.createConnection({
  host: "localhost",
  user: "root",
  password: "",
  database: "dbauth"
});

db.connect(err => {
  if (err) console.log(err);
  else console.log("Database terhubung");
});

app.listen(3000, () => {
  console.log("Server berjalan di port 3000");
});


    3.3 Register (Menyimpan User)

 app.post("/register", async (req, res) => {
  const { nama, email, password } = req.body;

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

  const sql = "INSERT INTO users (nama, email, password) VALUES (?, ?, ?)";

  db.query(sql, [nama, email, hashedPassword], (err, result) => {
    if (err) return res.status(400).json({ message: "Email sudah digunakan" });
    res.json({ message: "Register berhasil" });
  });
});


    3.4 Login (Membuat Token)

 app.post("/login", (req, res) => {
  const { email, password } = req.body;

  const sql = "SELECT * FROM users WHERE email = ?";
  
  db.query(sql, [email], async (err, results) => {
    if (err || results.length === 0)
      return res.status(400).json({ message: "User tidak ditemukan" });

    const user = results[0];

    const validPassword = await bcrypt.compare(password, user.password);
    if (!validPassword)
      return res.status(400).json({ message: "Password salah" });

    const token = jwt.sign(
      { id: user.id },
      "secretkey",
      { expiresIn: "1h" }
    );

    res.json({ message: "Login berhasil", token });
  });
});


    3.5 Middleware Verifikasi Token

 function auth(req, res, next) {
  const token = req.headers.authorization;
  if (!token) return res.status(401).json({ message: "Akses ditolak" });

  try {
    const verified = jwt.verify(token, "secretkey");
    req.user = verified;
    next();
  } catch (err) {
    res.status(400).json({ message: "Token tidak valid" });
  }
}

app.get("/profile", auth, (req, res) => {
  db.query("SELECT id, nama, email FROM users WHERE id = ?", 
  [req.user.id], 
  (err, results) => {
    res.json(results[0]);
  });
});


4. Kesimpulan

Mengganti MongoDB dengan MySQL sangat memungkinkan dan tidak mengubah konsep dasar autentikasi.

Perbedaannya hanya di:

  • MongoDB → pakai model Mongoose

  • MySQL → pakai query SQL

Konsep keamanan tetap sama:

  • Password harus di-hash

  • Gunakan JWT untuk autentikasi

  • Jangan hardcode secret key di production