Pendahuluan
Autentikasi adalah salah satu komponen utama dalam aplikasi web modern. Autentikasi memastikan bahwa pengguna yang mengakses aplikasi memiliki hak akses yang sesuai dengan perannya. JSON Web Token (JWT) adalah standar terbuka yang digunakan untuk memindahkan data antara pihak yang berpartisipasi secara aman. JWT sangat populer dalam autentikasi dan otorisasi pada aplikasi web.
Persiapan Project
Berikut yang perlu dipersiapkan:
- Node.js®
- DBMS (PostgreSQL Server atau MySQL Server)
- Postman
- Text Editor
1. Create Node.js Express Login App
$ mkdir auth-jwt
$ cd auth-jwt
$ npm init
{codeBox}
Selanjutnya, kita perlu menginstal beberapa library: express, cors, cookie, session, sequelize, mysql2, jsonwebtoken, dan bcryptjs.
Jalankan perintah berikut pada terminal:
npm install express mysql2 sequelize jsonwebtoken dotenv bcrypt cors express-session connect-session-sequelize
{codeBox}
selanjutnya kita install juga nodemon untuk menjalankan servernya
npm install -g nodemon
{codeBox}
dan ubah sedikit di bagian package.json:
2. Setup Config web server
Di folder auth-jwt kita, file .env :
ACCESS_TOKEN_SECRET = asdasd3124kansdknad3e3d
APP_PORT=5000
DB_CONNECTION=mysql
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=auth-jwt
DB_USERNAME=root
DB_PASSWORD=
{codeBox}
lalu sesuaikan configurasinya,untuk ACCESS_TOKEN_SECRET bisa di isi bebas
import Sequelize from "sequelize";
import dotenv from "dotenv";
dotenv.config();
const db = new Sequelize(
process.env.DB_DATABASE,
process.env.DB_USERNAME,
process.env.DB_PASSWORD,
{
host: process.env.DB_HOST,
dialect: process.env.DB_CONNECTION,
}
);
export default db;
{codeBox}
import express from "express";
import db from "./config/config.js";
import dotenv from "dotenv";
import Users from "./models/Users.js";
import session from "express-session";
import cors from "cors";
import router from "./routes/index.js";
import SequelizeStore from "connect-session-sequelize";
dotenv.config();
const app = express();
const sessionStore = SequelizeStore(session.Store);
const store = new sessionStore({
db: db,
});
try {
await db.authenticate();
//await Users.sync({ alter: true });
console.log("Database connected!");
} catch (error) {
console.error(error);
}
//store.sync();
app.use(
session({
secret: process.env.ACCESS_TOKEN_SECRET,
resave: false,
store: store,
saveUninitialized: true,
cookie: {},
})
);
app.use(cors({ credentials: true, origin: "http://localhost:3000" }));
app.use(express.json());
app.use(router);
app.listen(5000, () => console.log("Server running on port 5000..."));
{codeBox}
import Users akan error karena kita belum membuat modelnya
import router juga akan error karena kita belum membuat routernya
Users.sync() :
akan membuat table Users jika belum ada,
dan alter: true :
Perintah ini akan memeriksa status terkini tabel di database (kolom apa saja yang dimilikinya, tipe data apa yang digunakan, dll), dan kemudian melakukan perubahan yang diperlukan pada tabel agar sesuai dengan model.
3. Define the Sequelize Model
lalu kita perlu membuat user model seperti ini :
models/Users.js
import Sequelize from "sequelize";
import db from "../config/config.js";
const { DataTypes } = Sequelize;
const Users = db.define(
"users",
{
name: {
type: DataTypes.STRING,
},
email: {
type: DataTypes.STRING,
},
password: {
type: DataTypes.STRING,
},
},
{
freezedTableName: true,
}
);
export default Users;
{codeBox}
selanjutkan kalian bisa uncomment pada bagian Users di index.js:
import Users from "./models/Users.js";
await Users.sync({ alter: true });{codeBox}
4. Create Controller
controllers/Users.js
import Users from "../models/Users.js";
import bcrypt from "bcrypt";
import jwt from "jsonwebtoken";
export const getUser = async (req, res) => {
try {
const users = await Users.findAll({
attributes: ["id", "name", "email"],
});
const payload = {
name: req.name,
email: req.email,
};
res.status(200).json(users);
} catch (error) {
res.status(400).json({ msg: "Gagal mendapatkan data", success: false });
console.log(error.message);
}
};
export const Register = async (req, res) => {
try {
const { name, email, password } = req.body;
const users = await Users.findOne({
where: {
email: email,
},
});
if (users) {
return res.status(400).json({
success: false,
msg: "Email telah terdaftar",
});
}
const salt = await bcrypt.genSalt();
const hashPassword = await bcrypt.hash(password, salt);
await Users.create({
name: name,
email: email,
password: hashPassword,
});
res.json({ msg: "Register Berhasil", success: true });
} catch (error) {
res.status(400).json({ msg: "Gagal Register", success: false });
console.log(error.message);
}
};
export const Login = async (req, res) => {
try {
const user = await Users.findAll({
where: {
email: req.body.email,
},
});
const match = await bcrypt.compare(req.body.password, user[0].password);
if (!match)
return res
.status(400)
.json({ msg: "Email atau Password Salah", success: false });
const userId = user[0].id;
const name = user[0].name;
const email = user[0].email;
const accessToken = jwt.sign(
{ userId, name, email },
process.env.ACCESS_TOKEN_SECRET,
{
expiresIn: 86400, // 24 hours
}
);
const payload = {
name: name,
email: email,
token: accessToken,
};
console.log(payload);
req.session.token = payload;
res.json({
success: true,
msg: "Berhasil Login",accessToken
});
} catch (error) {
res.status(400).json({ msg: "Email atau Password Salah", success: false });
console.log(error.message);
}
};
export const Logout = async (req, res) => {
try {
req.session.destroy();
return res.status(200).send({
success: true,
message: "Berhasil signed out!",
});
} catch (err) {
res.status(400).json({ msg: "Tidak bisa signed out!", success: false });
console.log(err.message);
}
};
{codeBox}
5. Configure Auth Key
Fungsi jsonwebtoken seperti verify() atau sign() menggunakan algoritma yang memerlukan kunci rahasia (dalam bentuk String) untuk mengenkripsi dan mendekripsi token.
Di dalam folder auth-jwt/middleware, buatlah file Auth.js dengan kode berikut:
6.Create Middleware functions
middleware/Auth.js
import jwt from "jsonwebtoken";
export const verifyToken = (req, res, next) => {
try {
let token = req.session.token;
if (!token) {
return res.status(403).send({
success: false,
msg: "Tidak ada token!",
});
}
token = req.headers.authorization.split(" ")[1];
jwt.verify(token, process.env.ACCESS_TOKEN_SECRET, (err, decoded) => {
if (err)
return res.status(401).send({
success: false,
msg: "Token tidak terverifikasi!",
});
req.email = decoded.email;
req.name = decoded.name;
next();
});
} catch (error) {
res.status(401).json({ success: false, msg: "Not authorize" });
console.log(error.message);
}
};
{codeBox}
7. Define Routes
Authentication:
- POST /register
- POST /login
- GET /logout
User:
- GET /users
routes/index.js
import express from "express";
import { getUser, Register, Login, Logout } from "../controllers/Users.js";
import { verifyToken } from "../middleware/Auth.js";
const router = express.Router();
router.post("/register", Register);
router.post("/login", Login);
router.get("/logout", Logout);
//user
router.get("/users", verifyToken, getUser);
export default router;
{codeBox}
8.Run & Test
untuk menjalankan server ketikan di terminal :
nodemon index
{codeBox}
penampakan struktur akhir dari projectnya :
/login{codeBox}
/logout{codeBox}