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
