Si vous souhaitez protéger le contenu sensible de votre application Node, vous avez besoin d'un moyen d'authentifier les utilisateurs. Cependant, la création de votre propre système d'authentification est complexe, prend du temps et, si elle n'est pas effectuée correctement, peut introduire des vulnérabilités de sécurité dans votre application. Des outils tiers comme Passport facilitent l'authentification.

Dans ce didacticiel, vous apprendrez à implémenter l'authentification dans Node à l'aide de Passport et de MongoDB.

Que sont l'authentification et l'autorisation ?

Alors que l'authentification et l'autorisation sont parfois utilisées de manière interchangeable, ces deux concepts de sécurité ont des significations différentes. L'authentification est le processus de vérification qu'un utilisateur est bien celui qu'il prétend être tandis que l'autorisation est la processus permettant de déterminer si un utilisateur authentifié a accès à certaines parties de votre application.

Qu'est-ce que Passport.js ?

instagram viewer

Passeport.js (ou Passport) est un middleware d'authentification pour NodeJS qui fournit plus de 500 stratégies pour authentifier les utilisateurs, y compris passeport-local qui utilise un nom d'utilisateur et un mot de passe.

Ce tutoriel utilise passeport-local et passeport-jwt pour sécuriser les parcours.

Comment configurer l'authentification des utilisateurs dans NodeJS

Maintenant que vous en savez un peu plus sur l'authentification des utilisateurs et Passport.js, nous pouvons voir comment configurer l'authentification sur NodeJS. Ci-dessous, nous avons décrit les étapes que vous devrez suivre.

Étape 1: Configurer un serveur de nœuds

Créez un dossier nommé utilisateur-auth-nodejs et accédez-y à l'aide de votre terminal.

mkdir utilisateur-auth-nodejs. 

cd utilisateur-auth-nodejs

Prochaine initialisation package.json.

initialisation npm

Puisque vous utiliserez Express, un framework backend NodeJS, installez-le en exécutant la commande suivante.

npm j'exprime

Créez maintenant un fichier, app.js, et ajoutez le code suivant pour créer le serveur.

const express = require("express");
const app = express();
const PORT = 3000 ;
app.listen (PORT, () => {
console.log(`Écoute sur le port ${PORT}`);
});

En rapport: Apprenez à installer Npm et Node.js sur Ubuntu

Étape 2: configurer la base de données

Vous avez besoin d'une base de données pour stocker les données des utilisateurs. Vous utiliserez mongoose pour créer un schéma de données MongoDB qui définit la structure et le type de données que vous stockerez dans la base de données. Puisque vous stockez des données utilisateur, créez un schéma utilisateur.

Installez la mangouste.

npm je mangouste

Créer un nouveau fichier, userModel.js, et ajoutez ce qui suit.

const mangouste = exiger ('mangouste')
const {Schéma} = mangouste
const UserSchema = nouveau schéma ({
e-mail: {
type: Chaîne,
requis: vrai
},
le mot de passe: {
type: Chaîne,
requis: vrai
}
})
const UserModel = mongoose.model('user', UserSchema);
module.exports = UserModel ;

En rapport: Comment créer une base de données et une collection dans MongoDB

Avant de stocker le mot de passe, vous devez le crypter pour des raisons de sécurité. Vous utiliserez bcryptjs, un package npm très utile qui facilite l'utilisation de mots de passe chiffrés.

Installer bcryptjs.

npm je bcryptjs

Modifier usermodel.js pour crypter le mot de passe avant de l'enregistrer dans la base de données.

const mangouste = exiger ('mangouste')
const bcrypt = require('bcryptjs');
const {Schéma} = mangouste

const UserSchema = nouveau schéma ({
...
})
UserSchema.pre('save', fonction asynchrone (suivant) {
essayer {
// vérifier la méthode d'enregistrement
utilisateur constant = ceci ;
if (!user.isModified('password')) next();
// génère du sel
const sel = attendre bcrypt.genSalt (10);
// hache le mot de passe
const hashedPassword = attendre bcrypt.hash (this.password, sel);
// remplace le mot de passe en clair par un mot de passe haché
this.password = mot de passe haché ;
suivant();
} capture (erreur) {
retour suivant (erreur);
}
});
...
const User = mongoose.model('User', UserSchema);

Ici, vous utilisez un pré enregistrer crochet pour modifier le mot de passe avant qu'il ne soit enregistré. L'idée est de stocker la version hachée du mot de passe au lieu du mot de passe en texte brut. Un hachage est une longue chaîne complexe générée à partir d'une chaîne de texte brut.

Utiliser estModifié pour vérifier si le mot de passe change puisque vous n'avez qu'à hacher les nouveaux mots de passe. Ensuite, générez un sel et transmettez-le avec le mot de passe en texte brut à la méthode de hachage pour générer le mot de passe haché. Enfin, remplacez le mot de passe en texte brut par le mot de passe haché dans la base de données.

Créez db.js et configurez la base de données.

const mangouste = require("mangouste");
mangouste. Promesse = mondiale. Promettre;
const dbUrl = "mongodb://localhost/user" ;
const connect = asynchrone () => {
mongoose.connect (dbUrl, { useNewUrlParser: vrai, useUnifiedTopology: vrai });
const db = mangouste.connexion;
db.on("erreur", () => {
console.log("impossible de se connecter");
});
db.une fois("ouvrir", () => {
console.log("> Connexion réussie à la base de données");
});
};
module.exports = { connecter } ;

Dans app.js, connectez-vous à la base de données.

// se connecte à la base de données
const db = require('./db');
db.connect();

Étape 3: Configurer Passeport

Installer Passeport et passeport-local. Vous utiliserez ces packages pour enregistrer et connecter les utilisateurs.

npm i passeport
npm i passeport-local

Créer un nouveau fichier, passeportConfig.js, et importer passeport-local et le userModel.js.

const LocalStraregy = require("passport-local").Strategy;
const Utilisateur = require("./userModel");

Configurez Passport pour gérer l'enregistrement des utilisateurs.

const LocalStrategy = require("passport-local");
const Utilisateur = require("./userModel");
module.exports = (passeport) => {
passeport.use(
"inscription-locale",
nouvelle stratégie locale(
{
usernameField: "e-mail",
passwordField: "mot de passe",
},
asynchrone (email, mot de passe, terminé) => {
essayer {
// vérifie si l'utilisateur existe
const userExists = attendre User.findOne({ "email": email });
si (l'utilisateur existe) {
retour effectué (null, faux)
}
// Crée un nouvel utilisateur avec les données utilisateur fournies
const user = wait User.create({ email, password });
retour effectué (null, utilisateur);
} capture (erreur) {
fait (erreur);
}
}
)
);
}

Dans le code ci-dessus, vous vérifiez si l'e-mail est déjà utilisé. Si l'e-mail n'existe pas, enregistrez l'utilisateur. Notez que vous configurez également le champ du nom d'utilisateur pour accepter un e-mail. Par défaut, passeport-local attend un nom d'utilisateur, vous devez donc lui dire que vous lui transmettez plutôt un e-mail.

Utiliser passeport-local pour gérer également la connexion de l'utilisateur.

module.exports = (passeport) => {
passeport.use(
"inscription-locale",
nouvelle stratégie locale(
...
)
);
passeport.use(
"local-login",
nouvelle stratégie locale(
{
usernameField: "e-mail",
passwordField: "mot de passe",
},
asynchrone (email, mot de passe, terminé) => {
essayer {
const utilisateur = attendre User.findOne({ email: email });
if (!user) return done (null, false);
const isMatch = attendre user.matchPassword (mot de passe);
si (!estMatch)
retour effectué (null, faux);
// si les mots de passe correspondent renvoient l'utilisateur
retour effectué (null, utilisateur);
} capture (erreur) {
console.log (erreur)
retour effectué (erreur, faux);
}
}
)
);
};

Ici, vérifiez si l'utilisateur existe dans la base de données et, le cas échéant, vérifiez si le mot de passe fourni correspond à celui de la base de données. Notez que vous appelez également le matchPassword() méthode sur le modèle utilisateur alors allez à userModel.js fichier et ajoutez-le.

UserSchema.methods.matchPassword = fonction asynchrone (mot de passe) {
essayer {
return wait bcrypt.compare (password, this.password);
} capture (erreur) {
jeter une nouvelle erreur (erreur);
}
};

Cette méthode compare le mot de passe de l'utilisateur et celui de la base de données et renvoie true s'ils correspondent.

Étape 4: Configurer les routes d'authentification

Vous devez maintenant créer les points de terminaison auxquels les utilisateurs enverront des données. La première étape est la route d'inscription qui acceptera l'e-mail et le mot de passe d'un nouvel utilisateur.

Dans app.js, utilisez le middleware d'authentification de passeport que vous venez de créer pour enregistrer l'utilisateur.

app.post(
 "/auth/inscription",
passeport.authenticate('local-signup', { session: false }),
(req, res, suivant) => {
// S'inscrire
res.json({
utilisateur: req.user,
});
}
);

En rapport: Authentification contre Autorisation: quelle est la différence ?

En cas de succès, la route d'inscription doit renvoyer l'utilisateur créé.

Ensuite, créez la route de connexion.

app.post(
"/auth/login",
passeport.authenticate('local-login', { session: false }),
(req, res, suivant) => {
// connexion
res.json({
utilisateur: req.user,
});
}
);

Étape 5: Ajouter des itinéraires protégés

Jusqu'à présent, vous avez utilisé Passeport pour créer un middleware qui enregistre un utilisateur dans la base de données et un autre qui permet à un utilisateur enregistré de se connecter. Ensuite, vous allez créer un middleware d'autorisation pour protéger les routes sensibles à l'aide d'un jeton Web JSON (JWT). Pour mettre en œuvre l'autorisation JWT, vous devez :

  • Générer un jeton JWT.
  • Transmettez le jeton à l'utilisateur. L'utilisateur le renverra dans les demandes d'autorisation.
  • Vérifiez le jeton renvoyé par l'utilisateur.

Vous utiliserez le jsonwebtoken package pour gérer les JWT.

Exécutez la commande suivante pour l'installer.

npm je jsonwebtoken

Ensuite, générez un jeton pour chaque utilisateur qui se connecte avec succès.

Dans app.js, importer jsonwebtoken et modifiez la route de connexion comme ci-dessous.

app.post(
"/auth/login",
passeport.authenticate('local-login', { session: false }),
(req, res, suivant) => {
// connexion
jwt.sign({user: req.user}, 'secretKey', {expiresIn: '1h'}, (err, token) => {
si (erreur) {
return res.json({
message: "Échec de la connexion",
jeton: nul,
});
}
res.json({
jeton
});
})
}
);

Dans une application réelle, vous utiliseriez une clé secrète plus compliquée et la stockeriez dans un fichier de configuration.

La route de connexion renvoie un jeton en cas de succès.

Utiliser passeport-jwt pour accéder aux itinéraires protégés.

npm i passeport-jwt

Dans passeportConfig.js, configurez le passeport-jwt.

const JwtStrategy = require("passport-jwt").Strategy;
const { ExtractJwt } = require("passport-jwt")
module.exports = (passeport) => {
passeport.use(
"local-login",
nouvelle stratégie locale(
...
);
passeport.use(
nouveau JwtStrategy(
{
jwtFromRequest: ExtractJwt.fromHeader("autorisation"),
secretOrKey: "secretKey",
},
async (jwtPayload, fait) => {
essayer {
// Extraction de l'utilisateur
utilisateur constant = jwtPayload.user ;
done (null, utilisateur);
} capture (erreur) {
fait (erreur, faux);
}
}
)
);
};

Notez que vous extrayez le JWT de l'en-tête d'autorisation au lieu du corps de la demande. Cela empêche les pirates d'intercepter une demande et de saisir le jeton.

Pour voir comment passeport-jwt garde les itinéraires, créer un itinéraire protégé dans app.js.

app.get(
"/utilisateur/protégé",
passeport.authenticate("jwt", { session: false }),
(req, res, suivant) => {
res.json({user: req.user});
}
);

Seule une requête avec un JWT valide renvoie les données utilisateur.

Vous êtes maintenant prêt à faire passer votre authentification utilisateur au niveau supérieur

Dans ce didacticiel, vous avez appris comment authentifier les utilisateurs à l'aide d'un e-mail et d'un mot de passe à l'aide de Passport. Cela peut sembler intimidant au début, mais le processus est relativement simple. Vous pouvez aller encore plus loin et utiliser des fournisseurs d'identité tiers pris en charge par Passport tels que Twitter, Facebook et Google.

Qu'est-ce que l'authentification utilisateur et comment ça marche?

Il est important de comprendre les bases de l'authentification des utilisateurs pour garantir le niveau de sécurité maximal de vos comptes en ligne. Alors, plongeons dedans.

Lire la suite

PartagerTweeterE-mail
Rubriques connexes
  • Programmation
  • Programmation
  • Langages de programmation
  • Outils de programmation
A propos de l'auteur
Marie Gathoni (8 articles publiés)

Mary Gathoni est une développeuse de logiciels passionnée par la création de contenu technique non seulement informatif mais également engageant. Lorsqu'elle ne code pas ou n'écrit pas, elle aime passer du temps avec des amis et être à l'extérieur.

Plus de Mary Gathoni

Abonnez-vous à notre newsletter

Rejoignez notre newsletter pour des conseils techniques, des critiques, des ebooks gratuits et des offres exclusives !

Cliquez ici pour vous abonner