Introducció
Passport.js és un middleware d'autenticació per a Node.js que facilita la integració de diverses estratègies d'autenticació, com ara autenticació local, OAuth, OpenID, entre d'altres. En aquest tema, aprendrem a configurar Passport.js per a l'autenticació d'usuaris en una aplicació Node.js utilitzant Express.
Objectius
- Entendre què és Passport.js i com funciona.
- Configurar Passport.js en una aplicació Express.
- Implementar l'autenticació local amb Passport.js.
- Gestionar sessions d'usuari.
Requisits Previs
- Coneixements bàsics de Node.js i Express.
- Coneixements bàsics de bases de dades (utilitzarem MongoDB en aquest exemple).
Passos per Utilitzar Passport.js
- Instal·lació de Passport.js i Estratègies Necessàries
Primer, instal·lem Passport.js i l'estratègia local d'autenticació:
- Configuració de Passport.js
Creem un fitxer passport-config.js
per configurar Passport.js:
const LocalStrategy = require('passport-local').Strategy; const bcrypt = require('bcrypt'); const User = require('./models/User'); // Assumim que tenim un model d'usuari function initialize(passport) { const authenticateUser = async (email, password, done) => { const user = await User.findOne({ email: email }); if (user == null) { return done(null, false, { message: 'No user with that email' }); } try { if (await bcrypt.compare(password, user.password)) { return done(null, user); } else { return done(null, false, { message: 'Password incorrect' }); } } catch (e) { return done(e); } }; passport.use(new LocalStrategy({ usernameField: 'email' }, authenticateUser)); passport.serializeUser((user, done) => done(null, user.id)); passport.deserializeUser((id, done) => { User.findById(id, (err, user) => { done(err, user); }); }); } module.exports = initialize;
- Integració de Passport.js amb Express
Modifiquem el nostre fitxer principal de l'aplicació (per exemple, app.js
) per integrar Passport.js:
const express = require('express'); const app = express(); const passport = require('passport'); const session = require('express-session'); const flash = require('express-flash'); const initializePassport = require('./passport-config'); initializePassport(passport); app.use(express.urlencoded({ extended: false })); app.use(flash()); app.use(session({ secret: 'secret', resave: false, saveUninitialized: false })); app.use(passport.initialize()); app.use(passport.session()); app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login', failureFlash: true })); app.listen(3000);
- Creació de Rutes d'Autenticació
Creem les rutes necessàries per a l'autenticació:
app.get('/login', (req, res) => { res.render('login'); // Assumim que tenim una vista de login }); app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login', failureFlash: true })); app.get('/logout', (req, res) => { req.logout(); res.redirect('/login'); });
- Protecció de Rutes
Podem protegir rutes específiques per assegurar-nos que només els usuaris autenticats hi tinguin accés:
function checkAuthenticated(req, res, next) { if (req.isAuthenticated()) { return next(); } res.redirect('/login'); } app.get('/', checkAuthenticated, (req, res) => { res.render('index', { name: req.user.name }); });
Exercici Pràctic
Objectiu
Implementar l'autenticació d'usuaris en una aplicació Express utilitzant Passport.js.
Passos
- Crea una aplicació Express.
- Configura Passport.js seguint els passos anteriors.
- Implementa les rutes de registre, login i logout.
- Protegeix una ruta per assegurar-te que només els usuaris autenticats hi tinguin accés.
Solució
// app.js const express = require('express'); const app = express(); const passport = require('passport'); const session = require('express-session'); const flash = require('express-flash'); const initializePassport = require('./passport-config'); const mongoose = require('mongoose'); const bcrypt = require('bcrypt'); const User = require('./models/User'); mongoose.connect('mongodb://localhost/passportjs', { useNewUrlParser: true, useUnifiedTopology: true }); initializePassport(passport); app.use(express.urlencoded({ extended: false })); app.use(flash()); app.use(session({ secret: 'secret', resave: false, saveUninitialized: false })); app.use(passport.initialize()); app.use(passport.session()); app.set('view-engine', 'ejs'); app.get('/login', (req, res) => { res.render('login.ejs'); }); app.post('/login', passport.authenticate('local', { successRedirect: '/', failureRedirect: '/login', failureFlash: true })); app.get('/register', (req, res) => { res.render('register.ejs'); }); app.post('/register', async (req, res) => { try { const hashedPassword = await bcrypt.hash(req.body.password, 10); const user = new User({ name: req.body.name, email: req.body.email, password: hashedPassword }); await user.save(); res.redirect('/login'); } catch { res.redirect('/register'); } }); app.get('/logout', (req, res) => { req.logout(); res.redirect('/login'); }); function checkAuthenticated(req, res, next) { if (req.isAuthenticated()) { return next(); } res.redirect('/login'); } app.get('/', checkAuthenticated, (req, res) => { res.render('index.ejs', { name: req.user.name }); }); app.listen(3000);
Conclusió
En aquest tema, hem après a configurar Passport.js per a l'autenticació d'usuaris en una aplicació Node.js utilitzant Express. Hem vist com instal·lar i configurar Passport.js, com crear rutes d'autenticació i com protegir rutes per assegurar-nos que només els usuaris autenticats hi tinguin accés. Amb aquests coneixements, estem preparats per implementar autenticació en aplicacions més complexes.
Curs de Node.js
Mòdul 1: Introducció a Node.js
Mòdul 2: Conceptes Bàsics
Mòdul 3: Sistema de Fitxers i I/O
Mòdul 4: HTTP i Servidors Web
Mòdul 5: NPM i Gestió de Paquets
Mòdul 6: Framework Express.js
- Introducció a Express.js
- Configuració d'una Aplicació Express
- Middleware
- Routing en Express
- Gestió d'Errors
Mòdul 7: Bases de Dades i ORMs
- Introducció a les Bases de Dades
- Utilitzar MongoDB amb Mongoose
- Utilitzar Bases de Dades SQL amb Sequelize
- Operacions CRUD
Mòdul 8: Autenticació i Autorització
Mòdul 9: Proves i Depuració
- Introducció a les Proves
- Proves Unitàries amb Mocha i Chai
- Proves d'Integració
- Depuració d'Aplicacions Node.js
Mòdul 10: Temes Avançats
Mòdul 11: Desplegament i DevOps
- Variables d'Entorn
- Utilitzar PM2 per a la Gestió de Processos
- Desplegar a Heroku
- Integració i Desplegament Continu