Otentikasi Users Menggunakan Node ExpressJS Dan Passport.js
Banyak aplikasi Node.js mengharuskan users untuk mengautentikasi untuk mengakses konten pribadi. Proses otentikasi harus berfungsi dan aman, dan membuat proses otentikasi dari awal dapat memakan waktu dan membosankan. Untuk alasan ini, sebagian besar developer modern memilih untuk menggunakan perpustakaan tepercaya atau layanan eksternal. Passport.js adalah middleware Express populer yang dibuat khusus untuk memfasilitasi proses login. Fleksibel, dipercaya oleh banyak organisasi di seluruh dunia, dan mudah diintegrasikan ke dalam kode ExpressJS.
Dalam tutorial ini, Anda akan melakukan hal berikut:
- Buat form login untuk aplikasi Node Anda menggunakan passport
- Gunakan strategi otentikasi sessions dengan passport
- Hubungkan passport ke database MongoDB untuk menyimpan data users
- Izinkan hanya users yang masuk untuk mengakses halaman
Pada akhir tutorial ini, Anda akan belajar cara membuat halaman login fungsional dengan otentikasi dan otorisasi. Tutorial ini menjelaskan cara menggunakan Express.js untuk otentikasi users.
Tujuan
Buat aplikasi yang melakukan tugas otentikasi dan otorisasi dasar.
Prasyarat
- Apa perbedaan antara otorisasi dan otentikasi?
- Proses form login dengan ExpressJS
- Menyiapkan Express Session Authentication
Strategi passport.js
passport adalah perpustakaan fitur otentikasi yang dapat disesuaikan dengan kebutuhan sebagian besar aplikasi. Apa alasan fleksibilitas passport? Alasan utamanya adalah developer dapat memilih dari harta karun strategi implementasi. Strategi passport adalah modul terpisah yang disesuaikan dengan metode otentikasi individu. Strategi passport yang tersedia adalah:
- passport-local: Nama users lokal dan otentikasi kata sandi
- passport-facebook: Otentikasi dengan Facebook melalui OAuth
- Passport-Twitter: Otentikasi dengan Twitter melalui OAuth
- passport-jwt: gunakan Token Web JSON instance dari sessions
Ada ratusan strategi. Anda juga dapat menemukan modul yang disesuaikan dengan teknologi atau basis data khusus Anda. Misalnya, proyek ini menggunakan otentikasi lokal dengan MongoDB. Gunakan pembungkus MongoDB Mongoose dan modul passport-local-mongoose untuk fokus pada kode otorisasi.
MongoDB
MongoDB adalah database NoSQL yang menyimpan data menggunakan dokumen berformat JSON. Beberapa developer NodeJS lebih memilih MongoDB karena mereka akrab dengan JSON, yang mudah digunakan dengan objek JavaScript. Berikut ini adalah contoh data MongoDB.
{ name: 'Lori Fields',
address: {
street: 123 Palm Trace
city: Miami, FL
zip code: 33101
}
},
{ name: 'Harry Humbug',
address: {
street: 6 SW 1st Street
city: Deerfield Beach, FL
zip code: 33442
}
}
Aplikasi otentikasi menggunakan Passport dan ExpressJS
Sekarang setelah Anda memiliki gambaran umum tentang passport dan MongoDB, Anda siap untuk memulai proyek Anda. Struktur file dari aplikasi ini adalah sebagai berikut:
.
└── login
├── package.json
├── server.js
├── static
│ ├── index.html
│ ├── login.html
│ └── secret-page.html
└── user.js
Seperti yang Anda lihat, nama folder proyek utama adalah login. Saat masuk:
- Folder bernama static yang berisi file HTML
- Akar aplikasi Anda, server.js yang berisi semua kode server ExpressJS yang berisi root
- Gunakan Mongoose untuk terhubung ke database dan membuat model users user.js
- package.json, file konfigurasi
- Unduh MongoDB dan buat database
- Buat file package.json
- Instal ExpressJS dan dependensi
- Buat file HTML
- Buat user.js
- Hubungkan ke database
- Buat model users passport
- Buat dokumen MongoDB bernama 'userData'
URL koneksi: URL koneksi adalah "mongodb://localhost/users". "Localhost" adalahh host dan "users" adalah database. Jika database Anda berada di server eksternal, Anda mungkin perlu menyertakan lebih banyak parameter. Contoh:'mongodb://username:password@host:port/database? pilihan ...'
useNewUrlParser: Ini diatur untuk menghindari peringatan usang dari driver MongoDB asli. Keikutsertaan untuk memfasilitasi konversi aplikasi lama. Untuk developeran baru, setel ini ke true. Lihat dokumentasi Mongoose untuk informasi lebih lanjut.
useUnifiedTopology: Juga disetel untuk menghindari peringatan yang tidak digunakan lagi. Sederhananya, mesin manajemen koneksi telah ditingkatkan. Setel ke true untuk developeran baru, lihat dokumentasi Mongoose untuk detail selengkapnya.
Gunakan library passport-local-mongoose untuk mengekspor "users" dalam format yang dapat digunakan ke kode passport yang akan Anda buat.
Karena Anda mengekspor model sebagai modul, Anda dapat menggunakannya di server.js untuk membuat dokumen yang disebut "userData". userData menyimpan informasi users (id, username, hash). passport-local-mongoose secara otomatis akan memberi garam dan hash kata sandi Anda.
- Buat data users dummy
- Buat server.js
- bodyParser: Mengurai data yang disandikan URL dari badan
- passport.initialize: Middleware yang menggunakan Passport dengan Express
- passport.session: Anda harus menggunakan sessions ekspres di passport Anda
- Tentukan rute GET
- Nama users mereka: req.user.username (lebih dijelaskan di atas saat membuat file skema user.js)
- ID sessions mereka: req.sessionID
- Masa pakai cookie sessions maksimum: req.session.cookie.maxAge
- Tautan untuk keluar dari aplikasi:/logout
- Tautan ke halaman khusus anggota:/secret
- req.logout: Keluar dari users
- req.redirect: Mengarahkan users ke halaman lain. Dalam hal ini, users akan diarahkan ke /login.
- Tambahkan rute POST masuk
"Lokal": Strategi utama yang kami gunakan
failureRedirect: Jika users tidak mengautentikasi, users akan diarahkan ke halaman beranda.
console.log (req.user): Properti users dilampirkan ke req.user saat users mengautentikasi. Saat Anda menguji aplikasi ini, Anda akan melihat ID, nama users, garam, dan properti hash di perangkat Anda. Properti ini dapat bervariasi tergantung pada bagaimana Anda mendesain.
res.redirect (‘/ dashboard’): Ketika otentikasi users selesai, users akan diarahkan ke /dashboard. Tetapkan port ke aplikasi
- Uji kodenya
Buka Instal MongoDB Community Edition dan klik tautan untuk sistem operasi Anda (Linux, macOS, atau Windows). Ikuti petunjuk untuk menginstal dan meluncurkan MongoDB. Setelah menginstal dan meluncurkan MongoDB, buka shell perintah MongoDB.
mongo
Kemudian masuk ke database "users" (buat jika belum ada).
> use users
Anda dapat keluar dari shell perintah MongoDB kapan saja dengan memasukkan perintah quit.
> quit ()
Dengan asumsi Anda sudah menginstal NodeJS, buat file package.json di folder proyek utama Anda.
npm init -y
Sebelum Anda mulai menulis kode, Anda perlu menginstal dependensi yang diperlukan. Pertama, instal ExpressJS (kerangka server), body-parser (parsing badan permintaan masuk), dan sessions ekspres (middleware sessions berbasis cookie).
npm install express body-parser express-session
emudian instal Passport dan passport-local. passport adalah perpustakaan otentikasi dan passport-lokal adalah strategi otentikasi inti kami.
npm install passport passport-local
Selanjutnya, instal connect-ensure-login, middleware otentikasi yang memungkinkan Anda membatasi akses ke halaman Anda dengan mudah. Dibuat untuk bekerja dengan passport, satu panggilan fungsi hanya dapat menyetujui rute ke users yang masuk.
npm install connect-ensure-login
Selanjutnya, instal Mongoose, objek data mapper (ODM) yang digunakan untuk mengintegrasikan MongoDB dengan NodeJS. Pustaka ini menyederhanakan pemodelan data MongoDB dan memfasilitasi pembuatan objek JavaScript dan persistensi dokumen database. Asinkronnya fungsi kueri NodeJS dapat memperumit pemodelan data. Menggunakan Mongoose dalam proyek ini memungkinkan Anda untuk fokus pada kode otorisasi daripada pembuatan dokumen atau integrasi database.
npm install mongoose
Terakhir, instal passport-local-mongoose. Strategi ini mengintegrasikan luwak dengan strategi passport lokal.
npm install passport-local-mongoose
Pastikan semua file HTML ditulis dengan benar dan disimpan dalam direktori statis. Contoh index.html:
contoh index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>Welcome Home</title>
</head>
<body>
<a href="/login">Please Login Here!</a>
</body>
</html>
contoh login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Example Login Form</title>
</head>
<body>
<form action="//members.osiolabs.com/login" method="post">
<!-- user input-->
Username:<br>
<input type="text" name="username" placeholder="Username" required><br><br>
Password:<br>
<input type="password" name="password" placeholder="Password" required><br><br>
<!-- submit button -->
<input type="submit" value="login">
</form>
</body>
</html>
contoh secret-page.html:
<!DOCTYPE html>
<html lang="en">
<head>
<title>Secret Page</title>
</head>
<body>
<p align="justify">This is a secret page that is only available to logged-in users.
Congratulations!!! You are in on our secret!</p>
<a href="/logout">Log Out</a>
</body>
</html>
Mari kita buat user.js keluar dari kode database. kami akan:
Pertama, sertakan Mongoose dan passport-local-mongoose.
const mongoose = require('mongoose');
const passportLocalMongoose = require('passport-local-mongoose');
Kemudian sambungkan ke database "users" di server lokal. Jika server database tidak ada di mesin lokal Anda, tulis nama host atau alamat IP alih-alih "localhost".
mongoose.connect('mongodb://localhost/users',{
useNewUrlParser: true,
useUnifiedTopology: true
});
Selanjutnya, buat model users yang berisi dua properti: username dan password. Keduanya adalah tipe data string.
const Schema = mongoose.Schema;
const User = new Schema({
username: String,
password: String
});
Akhirnya, model siap untuk diekspor.
File user.js yang telah selesai akan terlihat seperti kode berikut.
// dependencies
const mongoose = require('mongoose');
const passportLocalMongoose = require('passport-local-mongoose');
// connect to database
mongoose.connect('mongodb://localhost/users',{
useNewUrlParser: true,
useUnifiedTopology: true
});
// Create Model
const Schema = mongoose.Schema;
const User = new Schema({
username: String,
password: String
});
// Export Model
User.plugin(passportLocalMongoose);
module.exports = mongoose.model('userData', User, 'userData');
Untuk menguji aplikasi Anda, Anda memerlukan data pengujian. Data uji adalah data sementara yang Anda masukkan ke dalam database untuk menguji kode Anda. Dalam aplikasi langsung, users mendaftar melalui form pendaftaran. Daftarkan dua untuk menguji kode otorisasi Anda.
const UserDetails = require('./user');
UserDetails.register({ username: 'candy', active: false }, 'cane');
UserDetails.register({ username: 'starbuck', active: false }, 'redeye');
Ini akan membuat dua users, cany dan starbuck, dengan kata sandi cane dan redeye.
Pada tahap awal developeran, ini adalah cara mudah untuk menambahkan data pengujian sementara ke database pengujian sementara. Anda tidak akan pernah menggunakan metode ini di server produksi. Cara lain untuk menyisipkan data termasuk melakukan migrasi dari baris perintah, menggunakan form (seperti form pendaftaran), dan menempatkan kode di atas dalam file migrasi data.
Jalankan kodenya.
node dummy-data.js
Sekarang Anda siap untuk membuat file root server.js untuk aplikasi Anda.
Pertama, sertakan dependensi.
const express = require('express'); // server software
const bodyParser = require('body-parser'); // parser middleware
const session = require('express-session'); // session middleware
const passport = require('passport'); // authentication
const connectEnsureLogin = require('connect-ensure-login'); //authorization
Juga, jangan lupa untuk menyertakan model users.
const User = require('./user.js'); // User Model
Selanjutnya, mari kita buat aplikasi Express.
const app = express();
Itu tidak diatur dalam modul passport-local-mongoose, jadi Anda perlu mengatur sessions ekspres. Untuk informasi tentang pengaturan sessions ekspres, periksa pengaturan untuk otentikasi sessions ekspres.
app.use(session({
secret: 'r8q,+&1LM3)CD*zAGpx1xm{NeQhc;#',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60 * 60 * 1000 } // 1 hour
}));
Anda perlu mengkonfigurasi middleware sedikit lagi:
app.use(bodyParser.urlencoded({ extended: false }));
app.use(passport.initialize());
app.use(passport.session());
Sebelum Anda dapat mengautentikasi, Anda perlu mendeklarasikan dan mengonfigurasi strategi Anda. Modul strategi kami, passport-local-mongoose, melakukan tugas yang membosankan untuk membuat strategi bagi kami, jadi yang Anda butuhkan hanyalah kode di bawah ini.
passport.use(User.createStrategy());
Jika Anda menggunakan passport-lokal instance passport-local-mongoose, Anda perlu mengonfigurasi strategi login Anda. Lihat contoh konfigurasi strategi lokal di bawah ini (tidak digunakan dalam proyek hari ini).
passport.use(new LocalStrategy(
// function of username, password, done(callback)
function(username, password, done) {
// look for the user data
User.findOne({ username: username }, function (err, user) {
// if there is an error
if (err) { return done(err); }
// if user doesn't exist
if (!user) { return done(null, false, { message: 'User not found.' }); }
// if the password isn't correct
if (!user.verifyPassword(password)) { return done(null, false, {
message: 'Invalid password.' }); }
// if the user is properly authenticated
return done(null, user);
});
}
));
Untuk mengautentikasi, passport pertama-tama melihat detail login users dan kemudian memanggil panggilan balik yang divalidasi (selesai). Jika users diautentikasi dengan benar, teruskan users ke panggilan balik. Jika users tidak diautentikasi dengan benar, berikan false ke panggilan balik. Anda juga memiliki opsi untuk meneruskan pesan tertentu ke panggilan balik.
Saat menggunakan sessions di passport, sessions baru dimulai segera setelah users diautentikasi dengan benar. Ketika ini terjadi, data users diserialkan ke dalam sessions dan ID users disimpan di req.session.passport.user. Untuk mengakses data users, deserialized menggunakan ID users sebagai kunci. Data users ditanyakan dan dilampirkan ke req.user.
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Sejauh ini, server.js akan terlihat seperti kode berikut.
const express = require('express'); // server software
const bodyParser = require('body-parser'); // parser middleware
const session = require('express-session'); // session middleware
const passport = require('passport'); // authentication
const connectEnsureLogin = require('connect-ensure-login');// authorization
const User = require('./user.js'); // User Model
const app = express();
// Configure Sessions Middleware
app.use(session({
secret: 'r8q,+&1LM3)CD*zAGpx1xm{NeQhc;#',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60 * 60 * 1000 } // 1 hour
}));
// Configure More Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(passport.initialize());
app.use(passport.session());
// Passport Local Strategy
passport.use(User.createStrategy());
// To use with sessions
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
Anda siap menambahkan rute GET ke kode server.js Anda. Mulailah dengan rute ke halaman rumah Anda. Siapapun bisa mengaksesnya.
app.get('/', (req, res) => {
res.sendFile(__dirname + '/static/index.html');
})
Selanjutnya, buat rute ke halaman login aplikasi Anda. Selain itu, siapa pun dapat mengaksesnya.
app.get('/login', (req, res) => {
res.sendFile(__dirname + '/static/login.html');
});
Selanjutnya, buat rute dasbor. Hanya users yang masuk yang dapat mengaksesnya.
app.get('/dashboard', connectEnsureLogin.ensureLoggedIn(), (req, res) => {
res.send(`Hello ${req.user.username}. Your session ID is ${req.sessionID}
and your session expires in ${req.session.cookie.maxAge}
milliseconds.<br><br>
<a href="/logout">Log Out</a><br><br>
<a href="/secret">Members Only</a>`);
});
Seperti disebutkan di atas, panggil fungsi connectEnsureLogin.ensureLoggedIn() di root handler sehingga hanya users yang masuk yang dapat mengakses halaman. Saat Anda menavigasi ke rute itu, itu mengirim pesan ke users yang masuk. Pesan tersebut meliputi:
Akar halaman rahasia juga hanya dapat diakses oleh users yang masuk.
app.get('/secret', connectEnsureLogin.ensureLoggedIn(), (req, res) => {
res.sendFile(__dirname + '/static/secret-page.html');
});
Terakhir, buat rute untuk logout users.
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/login');
});
Aplikasi ini berisi satu POST route/login. Dengan membuat rute ini, Anda siap untuk membuat proses otentikasi bekerja.
app.post('/login', passport.authenticate('local', { failureRedirect: '/' }), function(req, res) {
console.log(req.user)
res.redirect('/dashboard');
});
Panggil passport.authenticate pada route handler dan berikan dua parameter.
Jika users gagal mengautentikasi, users akan dikirim kembali ke halaman beranda. Jika mereka diautentikasi, kode dalam panggilan balik akan dieksekusi:
Anda siap untuk keluar dari server.js dengan menetapkan port.
// assign port
const port = 3000;
app.listen(port, () => console.log(`This app is listening on port ${port}`));
File server.js yang telah selesai akan terlihat seperti kode berikut.
const express = require('express'); // server software
const bodyParser = require('body-parser'); // parser middleware
const session = require('express-session'); // session middleware
const passport = require('passport'); // authentication
const connectEnsureLogin = require('connect-ensure-login');// authorization
const User = require('./user.js'); // User Model
const app = express();
// Configure Sessions Middleware
app.use(session({
secret: 'r8q,+&1LM3)CD*zAGpx1xm{NeQhc;#',
resave: false,
saveUninitialized: true,
cookie: { maxAge: 60 * 60 * 1000 } // 1 hour
}));
// Configure Middleware
app.use(bodyParser.urlencoded({ extended: false }));
app.use(passport.initialize());
app.use(passport.session());
// Passport Local Strategy
passport.use(User.createStrategy());
// To use with sessions
passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());
// Route to Homepage
app.get('/', (req, res) => {
res.sendFile(__dirname + '/static/index.html');
});
// Route to Login Page
app.get('/login', (req, res) => {
res.sendFile(__dirname + '/static/login.html');
});
// Route to Dashboard
app.get('/dashboard', connectEnsureLogin.ensureLoggedIn(), (req, res) => {
res.send(`Hello ${req.user.username}. Your session ID is ${req.sessionID}
and your session expires in ${req.session.cookie.maxAge}
milliseconds.<br><br>
<a href="/logout">Log Out</a><br><br><a href="/secret">Members Only</a>`);
});
// Route to Secret Page
app.get('/secret', connectEnsureLogin.ensureLoggedIn(), (req, res) => {
res.sendFile(__dirname + '/static/secret-page.html');
});
// Route to Log out
app.get('/logout', function(req, res) {
req.logout();
res.redirect('/login');
});
// Post Route: /login
app.post('/login', passport.authenticate('local', { failureRedirect: '/' }), function(req, res) {
console.log(req.user)
res.redirect('/dashboard');
});
// assign port
const port = 3000;
app.listen(port, () => console.log(`This app is listening on port ${port}`));
Proyek selesai dan Anda siap untuk menguji kode Anda. Pergi ke terminal, buka folder proyek utama (login) dan mulai server.
node server.js
Di browser web Anda, buka http://localhost:3000/. Halaman rumah ditampilkan. Silakan masuk dari sini Klik! Link untuk menuju halaman login. Kemudian masukkan kredensial login yang valid. Kemudian klik tombol login untuk masuk ke /dasbor.
Kemudian klik tautan Hanya Anggota untuk membuka / rahasia.
Terakhir, klik link Logout untuk mencegah akses ke /dasbor atau /rahasia ketika Anda tidak login. Anda juga dapat memastikan bahwa Anda diarahkan ke halaman rumah Anda jika Anda memasukkan informasi login yang salah.
kesimpulan
Passport.js adalah middleware otentikasi yang banyak digunakan yang memudahkan pembuatan aplikasi. developer dapat memilih dari berbagai strategi otentikasi yang sesuai dengan kebutuhan sebagian besar aplikasi. Dalam proyek ini, kami menggunakan passport-lokal untuk memverifikasi nama users dan kata sandi secara lokal.
Untuk database, kami menggunakan MongoDB, database NoSQL populer yang menyimpan data dalam dokumen JSON. Untuk menyederhanakan pemodelan data, kami menggunakan Mongoose untuk menangani interaksi antara NodeJS dan MongoDB. Ada ratusan modul strategi passport khusus yang tersedia dan saya memilih untuk menggunakan passport-local-mongoose.
Untuk menggunakan passport dengan ExpressJS, Anda perlu melakukan hal berikut:
- Hubungkan ke database
- Buat model users
- Konfigurasikan middleware yang tepat
- Konfigurasikan strategi passport
- Panggil fungsi passport.authenticate pada root POST login
- Setelah diautentikasi, req.user akan dibuat dan Anda akan dapat mengakses properti users.
Lebih memperdalam pemahaman
- Apa properti users lain yang ingin Anda gunakan selain nama users dan kata sandi Anda?
- Apa kelebihan dan kekurangan menggunakan ODM atau ORM?
- Mengapa tidak disarankan untuk menyimpan data users di file server?
- Dokumentasi Passport.js (passportjs.org)
- Dokumentasi MongoDB (mongodb.com)
- Dokumentasi mongoose (mongoosejs.com)
- passport-mongoose Lokal (npmjs.com)
Sumber daya tambahan