Menggunakan Passport Authentication Di Node JS - CRUDPRO

Menggunakan Passport Authentication Di Node JS

Menggunakan Passport Authentication Di Node JS

pengantar

Penting untuk dipahami bahwa framework Passport JS terdiri dari 2 library terpisah.

Yang pertama adalah pustaka "Passport JS" utama, dan yang kedua adalah pustaka "strategi" yang relevan.

  • Pustaka "Passport JS" utama selalu diperlukan, dan digunakan untuk memelihara informasi sesi untuk pengguna yang diautentikasi (yaitu Anda akan mengimpor pustaka ini terlepas dari jenis "Strategi" yang akan Anda gunakan untuk mengautentikasi pengguna).
  • Pustaka "strategi" sekunder bergantung pada metodologi yang Anda rencanakan untuk mengautentikasi pengguna. misalnya. "paspor-lokal", "paspor-facebook", "paspor-oauth-google" dll.

Kerangka kerja Passport JS mengabstraksi proses Login menjadi 2 bagian terpisah, "manajemen sesi" (dilakukan oleh "Perpustakaan Passport JS"), dan "otentikasi" (dilakukan oleh perpustakaan "Strategi" sekunder misalnya "paspor-lokal" atau "paspor-facebook" atau "paspor-oauth-google" dll.)

JS paspor:

Pustaka "Passport JS" terhubung dengan pustaka "sesi-ekspresi", dan membentuk perancah dasar untuk melampirkan informasi pengguna (diautentikasi) ke objek req.session. Pustaka Passport JS utama berurusan dengan pengguna yang sudah diautentikasi, dan tidak memainkan peran apa pun dalam mengautentikasi pengguna. Tujuan utamanya adalah untuk mempertahankan (melampirkan) pengguna (yang telah diautentikasi) ke sesi.

$ npm i passport
$ npm i express-session// Install the primary "Passport JS" library, and the "express-session" library// The main "passport" library piggybacks on the "express-session" library, so in order to use "passport" you will have to install "express-session.
Pustaka Otentikasi:

Perpustakaan sekunder digunakan untuk mengotentikasi pengguna. Pengguna dapat diautentikasi terhadap nama pengguna/kata sandi yang disimpan dalam database yang Anda buat baik secara lokal atau di cloud (disebut "Strategi Lokal"), ATAU pengguna dapat diautentikasi dengan meminta mereka masuk ke akun Google mereka ("Strategi Otentikasi Google") , atau Facebook, atau akun Github.

Jadi pustaka sekunder yang Anda impor akan didasarkan pada mekanisme aktual yang ingin Anda gunakan untuk "mengotentikasi" pengguna.

Install the secondary library based on the methodology or "Strategy" you will use to authenticate users.Eg. $ npm i passport-local
// in case you will be authenticating by comparing with username and password store in your DB ("Local Strategy")OR$ npm i passport-google-oauth
// in case you will be authenticating using Google loginOR$ npm i passport-facebook
// in case you will be authenticating using Facebook login

Passport JS — Langkah dan Sintaks

Langkah-langkah berikut menunjukkan sintaks paspor dasar untuk mengintegrasikan "Passport JS" ke dalam aplikasi NodeJS Express Anda.

Langkah 1: Impor pustaka ke dalam file Anda
//Import Express
const express = require('express')
const app = express()//Import the main Passport and Express-Session library
const passport = require('passport')
const session = require('express-session')//Import the secondary "Strategy" library
const LocalStrategy = require('passport-local').Strategy// In this example we will use the "local" strategy
Langkah 2: Inisialisasi Middleware
app.use(session({
  secret: "secret",
  resave: false ,
  saveUninitialized: true ,
}))
// This is the basic express session({..}) initialization.app.use(passport.initialize()) 
// init passport on every route call.app.use(passport.session())    
// allow passport to use "express-session".
Langkah 3: Gunakan Paspor untuk menentukan Strategi Otentikasi
passport.use(new LocalStrategy (authUser))// The "authUser" is a function that we will define later will contain the steps to authenticate a user, and will return the "authenticated user".
Langkah 3a: Tentukan fungsi "authUser" untuk mendapatkan Pengguna yang diautentikasi

Fungsi “authUser” adalah fungsi panggilan balik yang diperlukan dalam LocalStrategy, dan dapat menggunakan tiga argumen. "Pengguna" dan "kata sandi" diisi dari "req.body.username" dan "req.body.password". Ini dapat digunakan untuk mencari DB untuk menemukan dan mengautentikasi nama pengguna/kata sandi yang dimasukkan dalam formulir "login".

authUser = (user, password, done) => {//Search the user, password in the DB to authenticate the user//Let's assume that a search within your DB returned the username and password match for "Kyle".   let authenticated_user = { id: 123, name: "Kyle"}   return done (null, authenticated_user )
}

Fungsi “done()” kemudian digunakan untuk meneruskan “{authenticated_user}” ke fungsi serializeUser().

Perhatikan, fungsi done(<err>, <user>) di “authUser” diteruskan sebagai ,

1. If the user not found in DB, 
done (null, false)2. If the user found in DB, but password does not match, 
done (null, false)3. If user found in DB and password match, 
done (null, {authenticated_user})

i.e.

  • jika pengguna tidak ditemukan, selesai( <tidak ada kesalahan> jadi nol, <tidak ada pengguna yang cocok> jadi salah),
  • jika pengguna ditemukan tetapi kata sandi tidak cocok, selesai ( <no error> jadi nol, <tidak ada pengguna yang cocok> jadi salah)
  • jika pengguna menemukan dan kata sandi cocok, kami menemukan pengguna yang diautentikasi dan selesai ( <tidak ada kesalahan> jadi null, <berikan pengguna yang diautentikasi ke serializeUser()>)

Langkah 4: Buat serial dan De-Serialisasi (diautentikasi) pengguna

Pengguna Berseri:
passport.serializeUser( (userObj, done) => { 
	done(null, userObj)
})
------------------------ 
	
APA YANG DILAKUKAN SERIALISASI PENGGUNA BERARTI?
1. "sesi-ekspres" membuat "req.session" objek, saat dipanggil melalui app.use(session({..}))
2. "paspor" lalu tambahkan objek tambahan "req.session.passport" ke "req.session" ini.
3. Semua fungsi serializeUser() adalah,
menerima "pengguna yang diautentikasi" objek dari "Strategi" framework, dan lampirkan pengguna yang diautentikasi ke "req.session.passport.user.{..}"Dalam kasus di atas, kami menerima {id: 123, name: "Kyle"} dari done()

di fungsi authUser dalam kerangka Strategi,
jadi ini akan dilampirkan sebagai
req.session.passport.user.{id: 123, nama: "Kyle"}

3. Jadi berlaku selama "serializeUser", pustaka PassportJS menambahkan pengguna yang diautentikasi ke akhir "req.session.passport" obyek.
Inilah yang dimaksud dengan serialisasi.

Ini memungkinkan pengguna yang diautentikasi untuk "dilampirkan" ke sesi yang unik.

Inilah mengapa pustaka PassportJS digunakan, karena pustaka ini mengabstraksinya dan secara langsung mengelola pengguna yang diautentikasi untuk setiap sesi dalam "req.session.passport.user.{..}"

----------- -----------------
De-serialisasi Pengguna:

Sekarang kapan pun kita menginginkan detail pengguna untuk sebuah sesi, kita cukup mendapatkan objek yang disimpan di “req.session.passport.user.{..}”.

Kami dapat mengekstrak informasi pengguna dari objek {..} dan melakukan pencarian tambahan di basis data kami untuk pengguna tersebut untuk mendapatkan informasi pengguna tambahan, atau untuk sekadar menampilkan nama pengguna di dasbor.

Menggunakan Passport Authentication Di Node JS

Langkah 5: Gunakan passport.authenticate() sebagai middleware pada rute login Anda

Sekarang Anda dapat menggunakan fungsi passport.authenticate() di dalam app.post() dan menentukan successRedirect dan failureRedirect,

app.post ("/login", passport.authenticate('local', {
   successRedirect: "/dashboard",
   failureRedirect: "/login",
}))

'Lokal' menandakan bahwa kita menggunakan strategi 'lokal'. Jika Anda menggunakan google atau facebook untuk mengotentikasi, itu akan mengatakan 'google' atau 'facebook', bukan 'lokal'.

Langkah 6: Gunakan fungsi “req.isAuthenticated()” untuk melindungi rute yang masuk

Passport JS dengan nyaman menyediakan fungsi "req.isAuthenticated()", yaitu

  • mengembalikan "true" jika ada pengguna yang diautentikasi di "req.session.passport.user", atau
  • mengembalikan "false" jika tidak ada pengguna yang diautentikasi di "req.session.passport.user".

Fungsi “req.isAuthenticated()” dapat digunakan untuk melindungi rute yang hanya dapat diakses setelah pengguna login misalnya. dasbor.

Create a function as follows,
------------checkAuthenticated = (req, res, next) => {
  if (req.isAuthenticated()) { return next() }
  res.redirect("/login")
}------------Now you can use this function as middleware to protect your routes as follows,app.get("/dashboard", checkAuthenticated, (req, res) => {
  res.render("dashboard.ejs", {name: req.user.name})
})

Demikian pula, jika pengguna sudah masuk dan mencoba mengakses layar "register" atau "login", Anda dapat mengarahkan mereka ke layar "dashboard" (terlindungi).

Demikian pula, jika pengguna sudah masuk dan mencoba mengakses layar "register" atau "login", Anda dapat mengarahkan mereka ke layar "dashboard" (terlindungi).

Create a function as follows,
-----------checkLoggedIn = (req, res, next) => {
  if (req.isAuthenticated()) { 
       return res.redirect("/dashboard")
   }
  next()
}------------Now you can use this function as middleware to as follows,app.get("/login", checkLoggedIn, (req, res) => {     
     res.render("login.ejs")
})

Langkah 7: Gunakan "req.logOut()" untuk menghapus objek sesi

Passport JS juga dengan mudah memberi kita fungsi "req.logOut()", yang ketika dipanggil akan menghapus objek "req.session.passport" dan menghapus semua parameter yang terpasang.

Ini dapat digunakan untuk mengimplementasikan logout sebagai berikut,

app.delete("/logout", (req,res) => {
   req.logOut()
   res.redirect("/login")
   console.log(`-------> User Logged out`)
})

Perhatikan bahwa ketika fungsi req.logOut() dipanggil, fungsi "req.session.passport" dan "req.user" akan dihapus.

"req.session.passport" -------> {}
"req.user" ------->  undefined
Paspor JS — Sedang beraksi

Untuk benar-benar melihat apa yang terjadi di balik layar, dan apa sebenarnya yang dilakukan paspor, kita akan menggunakan contoh sederhana berikut.

const express = require('express')
const app = express()

const session = require('express-session')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy

app.use(express.urlencoded({extended: false}))

//Middleware
app.use(session({
    secret: "secret",
    resave: false ,
    saveUninitialized: true ,
}))

app.use(passport.initialize()) // init passport on every route call
app.use(passport.session())    //allow passport to use "express-session"

authUser = (user, password, done) => {
    console.log(`Value of "User" in authUser function ----> ${user}`)         //passport will populate, user = req.body.username
    console.log(`Value of "Password" in authUser function ----> ${password}`) //passport will popuplate, password = req.body.password

// Use the "user" and "password" to search the DB and match user/password to authenticate the user
// 1. If the user not found, done (null, false)
// 2. If the password does not match, done (null, false)
// 3. If user found and password match, done (null, user)
    
    let authenticated_user = { id: 123, name: "Kyle"} 
//Let's assume that DB search that user found and password matched for Kyle
    
    return done (null, authenticated_user ) 
}


passport.use(new LocalStrategy (authUser))

passport.serializeUser( (user, done) => { 
    console.log(`--------> Serialize User`)
    console.log(user)     

    done(null, user.id)
  
// Passport will pass the authenticated_user to serializeUser as "user" 
// This is the USER object from the done() in auth function
// Now attach using done (null, user.id) tie this user to the req.session.passport.user = {id: user.id}, 
// so that it is tied to the session object

} )


passport.deserializeUser((id, done) => {
        console.log("---------> Deserialize Id")
        console.log(id)

        done (null, {name: "Kyle", id: 123} )      
  
// This is the id that is saved in req.session.passport.{ user: "id"} during the serialization
// use the id to find the user in the DB and get the user object with user details
// pass the USER object in the done() of the de-serializer
// this USER object is attached to the "req.user", and can be used anywhere in the App.

}) 


//Middleware to see how the params are populated by Passport
let count = 1

printData = (req, res, next) => {
    console.log("\n==============================")
    console.log(`------------>  ${count++}`)

    console.log(`req.body.username -------> ${req.body.username}`) 
    console.log(`req.body.password -------> ${req.body.password}`)

    console.log(`\n req.session.passport -------> `)
    console.log(req.session.passport)
  
    console.log(`\n req.user -------> `) 
    console.log(req.user) 
  
    console.log("\n Session and Cookie")
    console.log(`req.session.id -------> ${req.session.id}`) 
    console.log(`req.session.cookie -------> `) 
    console.log(req.session.cookie) 
  
    console.log("===========================================\n")

    next()
}

app.use(printData) //user printData function as middleware to print populated variables

app.listen(3001, () => console.log(`Server started on port 3001...`))

app.get("/login", (req, res) => {
    res.render("login.ejs")

})

app.post ("/login", passport.authenticate('local', {
    successRedirect: "/dashboard",
    failureRedirect: "/login",
}))

app.get("/dashboard", (req, res) => {   
    res.render("dashboard.ejs", {name: req.user.name})
})

File "login.ejs" dan "dashboard.ejs" ada di folder /views, dan sangat mendasar.

  • "Dashboard.ejs" hanya akan menampilkan "nama" pengguna yang masuk.
    <h1> <%= name %> is logged in </h1>
  • The "index.ejs" adalah bentuk sederhana yang menerima "username" dan "password"
    <h1> Login </h1><form action="/login" method="POST">   USER <input type="text" name="username">
       PASSWORD <input type="password" name="password">
       <button type="submit"> Submit </button>
    </form>
1: Jalankan app.js di atas dan kunjungi http://localhost:3001/login, Anda akan melihat yang berikut,
Menggunakan Passport Authentication Di Node JS

console.log() akan menampilkan yang berikut,

Menggunakan Passport Authentication Di Node JS
Menggunakan Passport Authentication Di Node JS
2: Masukkan beberapa nama pengguna dan kata sandi, dan klik kirim
Menggunakan Passport Authentication Di Node JS
Menggunakan Passport Authentication Di Node JS

console.log() akan menampilkan yang berikut,

Menggunakan Passport Authentication Di Node JS
Menggunakan Passport Authentication Di Node JS

Dan Selesai!

Kuncinya adalah bahwa kerangka kerja paspor terdiri dari pustaka "Passport JS" utama (yang digunakan untuk mengelola sesi menggunakan "sesi-ekspres" dan lampirkan {authenticated_user} ke "req.session.passport"), dan "sekunder" Perpustakaan Strategi” (mis. “otentikasi lokal”, atau “autentikasi google” atau “autentikasi facebook”), yang digunakan untuk mengautentikasi pengguna, dan meneruskan “pengguna_otentikasi” ini ke pustaka Paspor utama.

Ringkasan langkah-langkah untuk mengintegrasikan Passport JS adalah,

Menggunakan Passport Authentication Di Node JS

Perhatikan bahwa untuk mengintegrasikan Passport JS ke dalam aplikasi Anda, Anda akan selalu mengikuti semua langkah [1–7] di atas, terlepas dari “strategi” yang Anda gunakan untuk mengautentikasi. Satu-satunya hal yang akan berubah adalah, — Pada Langkah 3, Anda akan menentukan "Strategi" yang ingin Anda gunakan untuk mengautentikasi. — Pada Langkah 3a, fungsi "authUser" akan disesuaikan dengan "strategi" yang Anda gunakan untuk mendapatkan "authenticated_user"

Jadi Passport JS sepenuhnya membakukan "manajemen sesi", dan Anda selalu dapat menggunakan "req.user", "req.isAuthenticated()", "req.logOut" dalam aplikasi NodeJS Anda yang menggunakan Passport JS, terlepas dari jenis " Perpustakaan "strategi" yang Anda gunakan untuk mengotentikasi pengguna yaitu "strategi-lokal", "facebook", "google", dll.