Senangnya kita telah menyelesaikan CRUD pada database, sekarang yang kita inginkan adalah data yang aman, yang berhak yang boleh mengubah atau menghapus data tersebut.
Authentication
Pada tabel user
kita telah memiliki beberapa kolom yaitu id, name, label, picture, email, phone, website, summary tetapi untuk melakukan login kita butuh setidaknya email dan password, karena itu kita akan menambahkan kolom password
.
Tambah Kolom Sequelize
Untuk menambahkan kolom pada sequelize, lakukan peintah berikut.
sequelize migration:create --name add_column_password
Sehingga menghasilkan file migrasi, seperti gambar berikut.
Ubah isi file migrasi tersebut sehingga menjadi seperti berikut.
"use strict";
module.exports = {
up: (queryInterface, Sequelize) => {
return queryInterface.addColumn("Users", "password", Sequelize.STRING);
},
down: (queryInterface, Sequelize) => {
return queryInterface.removeColumn("Users", "password");
},
};
Kemudian migrasi tersebut kita terapkan ke database dengan perintah berikut.
sequelize db:migrate
Jika kolom telah kita tambahkan, jangan lupa ubah model agar sesuai dengan tabel. Ubah file user.js
sehingga menjadi seperti berikut.
"use strict";
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define(
"User",
{
name: DataTypes.STRING,
label: DataTypes.STRING,
picture: DataTypes.STRING,
email: DataTypes.STRING,
phone: DataTypes.STRING,
website: DataTypes.STRING,
summary: DataTypes.STRING,
password: DataTypes.STRING,
},
{}
);
User.associate = function (models) {
// associations can be defined here
};
return User;
};
Register User
Proses register merupakan proses untuk mendaftarkan identitas yang memiliki kunci untuk masuk kembali. Data yang bersifat sensitif harus kita lakukan encripsi. Pada kasus ini kita butuh library bcryptjs
yang berfungsi untuk mengencripsi data. Intall bcryptjs dengan cara.
npm i bcryptjs
Pastikan pada file package.json
, bcryptjs telah tersedia.
Ubah function createUser
pada file user.controller.js
dan tambahkan bcryptjs.
const model = require("../models");
const bcrypt = require("bcryptjs");
function createUser(req, res) {
let salt = bcrypt.genSaltSync(10);
let hash = bcrypt.hashSync(req.body.password, salt);
model.User.create({
name: req.body.name,
label: req.body.label,
picture: req.body.picture,
email: req.body.email,
phone: req.body.phone,
website: req.body.website,
summary: req.body.summary,
password: hash,
})
.then(function (result) {
res.json(result);
})
.catch(function (error) {
res.json({ error: error });
});
}
Perhatikan hasil register pada insomnia.
Token User
Pada sebuah aplikasi setelah seseorang login maka dibutuhkan token sebagai credential terpercaya untuk mengelola data, misal update atau mungkin hapus.
Kalau dicontohkan ke kehidupan nyata email dan password adalah tiket untuk naik pesawat yang ditukarkan saat check in hingga mendapatkan boarding pass. Boarding pass inilah yang kita gunakan untuk masuk ke pesawat. Sama halnya dengan token, token didapatkan setelah login dilakukan, sehingga token dikirim bersamaan dengan akses pada server lebih dalam.
Untuk membuat token kita menggunakan library jsonwebtoken
, install dengan cara berikut.
npm i jsonwebtoken
Tambahkan function loginUser
pada file user.controller.js
, yang isinya seperti berikut.
const model = require("../models");
const bcrypt = require("bcryptjs");
const jwt = require("jsonwebtoken");
function loginUser(req, res) {
const email = req.body.email;
const password = req.body.password;
model.User.findOne({
where: {
email: email,
},
})
.then(function (result) {
let passwordHash = result.password;
let checkPassword = bcrypt.compareSync(password, passwordHash);
if (checkPassword) {
res.json({
message: "Berhasil Login",
token: jwt.sign({ id: result.id }, "asrul-dev"),
});
} else {
res.json({
message: "Gagal Login",
});
}
})
.catch(function (error) {
res.json({ error: error });
});
}
Jangan lupa tambahkan route pada file user.route.js
, sehingga menjadi seperti berikut.
const router = require("express").Router();
const userController = require("../controller/user.controller.js");
router.post("/login", userController.loginUser);
router.post("/", userController.createUser);
router.get("/", userController.readUser);
router.put("/:id", userController.updateUser);
router.delete("/:id", userController.deleteUser);
module.exports = router;
Tes menggunakan insomia.
Akhirnya berhasil juga, tapi tidak sampai disitu kita harus melakukan autorize, yaitu memberi hak akses terhadap aktifitas data. Seperti update dan delete pada kasus ini hanya boleh dilakukan orang yang memiliki akun tersebut.
Authorize
Penggunaan authorize kita harus membuat middleware, middleware adalah perantara route dan controller, sehingga ketika melewati route menuju controller akan dilakukan pemeriksaan, apakah memiliki autorize atau tidak.
Buat file baru dengan nama auth.js
dalam folder middlewares
, yang isinya berikut.
const jwt = require("jsonwebtoken");
const model = require("../models");
module.exports = (req, res, next) => {
let token = req.headers.token;
if (token) {
let verify = jwt.verify(token, "asrul-dev");
model.User.findOne({
where: {
id: verify.id,
},
})
.then(function (result) {
if (result) {
req.decoded = verify;
next();
} else {
res.status(401).json({
message: "Kamu tak punya akses",
});
}
})
.catch(function (error) {
res.json({ error: error });
});
} else {
res.status(401).json({
message: "Silahkan Login Dahulu",
});
}
};
Kemudian ubah route user.router.js
menjadi seperti berikut.
const router = require("express").Router();
const userController = require("../controller/user.controller.js");
const auth = require("../middlewares/auth.js");
router.post("/login", userController.loginUser);
router.post("/", userController.createUser);
router.get("/", userController.readUser);
router.put("/:id", auth, userController.updateUser);
router.delete("/:id", auth, userController.deleteUser);
module.exports = router;
Pada saat update dan delete, jika yang mengakses bukan yang login maka data dilarang diubah atau dihapus. Untuk melakukan itu ubah function updateUser
dan function deleteUser
menjadi seperti berikut.
function updateUser(req, res) {
let decodedId = req.decoded.id;
if (Number(decodedId) === Number(req.params.id)) {
model.User.update(
{
name: req.body.name,
label: req.body.label,
picture: req.body.picture,
email: req.body.email,
phone: req.body.phone,
website: req.body.website,
summary: req.body.summary,
},
{
where: {
id: req.params.id,
},
}
)
.then(function (result) {
res.json(result);
})
.catch(function (error) {
res.json({ error: error });
});
} else {
res.json({
message: "Ini bukan data Anda",
});
}
}
function deleteUser(req, res) {
let decodedId = req.decoded.id;
if (Number(decodedId) === Number(req.params.id)) {
model.User.destroy({
where: {
id: req.params.id,
},
})
.then(function (result) {
res.json(result);
})
.catch(function (error) {
res.json({ error: error });
});
} else {
res.json({
message: "Ini bukan data Anda",
});
}
}
Kita uji pada insomnia dengan skenario, token adalah milik user dengan id 3, tetapi yang akan dihapus adalah user id 4.