En tant que développeur, il est de votre responsabilité de protéger les données de vos utilisateurs grâce à l'authentification. Vous pouvez utiliser Passport.js pour authentifier les utilisateurs dans une application Node et Postgres.

Commencez par créer un serveur Node avec des points de terminaison pour enregistrer, connecter et déconnecter les utilisateurs. Vous pouvez laisser Passport gérer l'authentification pour restreindre l'accès non autorisé à votre application.

Création d'une table d'utilisateurs

Pour l'authentification de l'utilisateur, vous utiliserez un email et un mot de passe. Cela signifie que la table des utilisateurs doit contenir un e-mail et un champ de mot de passe. Dans l'invite de commande psql, créez une nouvelle base de données appelée nodeapp :

CRÉERBASE DE DONNÉES nodeapp ;

Ensuite, créez une table pour stocker les utilisateurs :

CRÉERTABLEutilisateurs (
id INT GÉNÉRÉ TOUJOURS COMME CLÉ PRIMAIRE D'IDENTITÉ,
e-mail CHAR(128),
mot de passe CHAR(60)
);

Ce code créera une nouvelle table contenant l'adresse e-mail, le mot de passe et un champ d'identification généré automatiquement.

Création d'un serveur de nœud

Node.js est un environnement d'exécution JavaScript côté serveur qui nous permet de créer rapidement des serveurs HTTP. Pour simplifier le processus de création du serveur et des différentes routes HTTP, vous pouvez utiliser Express, un framework web Node.js.

Exécutez cette commande pour créer un nouveau dossier appelé postgres-auth :

mkdir postgres-auth

Ensuite, initialisez npm :

npm init -y

Enfin, installez Express :

npm installer express

Tu peux maintenant créer le serveur Web Node.

Dans un nouveau fichier nommé index.js, ajoutez ce qui suit :

constante exprimer = exiger("Express");
constante app = express();
app.use (express.json());
app.use (express.urlencodé({ étendu: vrai }));
app.listen(3000, () => console.log("Écoute sur le port 3000"));

L'exécution de ce code démarrera le serveur et consignera les éléments suivants dans la console :

Ecoute sur le port 3000

Connexion à PostgreSQL

À se connecter à PostgreSQL utilisation noeud-postgres. node-postgres est un pilote de connexion qui fournit une interface entre Node et Postgres.

Exécutez la commande suivante pour installer node-postrges via npm :

npm installer la page

Une fois que vous avez installé cette bibliothèque, créez un nouveau fichier appelé db.js et connectez-le à la base de données :

constante {Client} = exiger("page");
constante { utilisateur, hôte, base de données, mot de passe, port } = exiger(""./dbConfig");

constante client = Nouveau Client({
utilisateur,
héberger,
base de données,
le mot de passe,
Port,
});

client.connect();
module.exports = client ;

La méthode client de node-postgres prend les détails de la base de données à laquelle vous vous connectez. Ce programme importe ses détails de connexion à partir d'un fichier appelé dbConfig. Par conséquent, créez ce fichier et ajoutez-y le code suivant :

module.exports = {
utilisateur: "postgres",
hôte: "localhost",
base de données: "nodeapp",
mot de passe: "votreMotdePasse",
Port: 5432,
};

Créer des fonctions d'assistance de base de données

Il est toujours recommandé d'utiliser des fonctions individuelles pour interagir avec la base de données. Ils facilitent l'écriture de tests unitaires et améliorent la réutilisation. Pour le point de terminaison d'inscription, vous devez créer deux fonctions :

  1. Pour vérifier si l'e-mail est déjà enregistré.
  2. Pour créer l'utilisateur.

L'objectif est de n'enregistrer un utilisateur que s'il n'existe pas dans la base de données.

Créez un nouveau fichier appelé helper.js et importez le client de base de données à partir de db.js :

constante client = exiger(""./db.js")

Ensuite, ajoutez une nouvelle fonction appelée emailExists() :

constante emailExists = asynchrone (courriel) => {
constante données = attendre client.query("SELECT * FROM utilisateurs WHERE email=$1", [
e-mail,
]);

si (data.rowCount == 0) revenirfaux;
revenir données.lignes[0];
};

Cette fonction prend un e-mail et vérifie s'il est déjà utilisé. Pour ce faire, il utilise la clause SELECT qui renvoie une ligne contenant un champ de courrier électronique correspondant à la valeur fournie par l'utilisateur qui s'enregistre. Si l'e-mail n'existe pas, il renvoie faux.

Pour créer une fonction qui crée l'utilisateur, ajoutez une fonction appelée createUser() à helper.js :

constante créerutilisateur = asynchrone (email, mot de passe) => {
constante sel = attendre bcrypt.genSalt(10);
constante hachage = attendre bcrypt.hash (mot de passe, sel);

constante données = attendre client.query(
"INSERT INTO utilisateurs (email, mot de passe) VALUES ($1, $2) RETOUR identifiant, email, mot de passe",
[courriel, hachage]
);

si (data.rowCount == 0) revenirfaux;
revenir données.lignes[0];
};

Cette fonction prend les valeurs d'email et de mot de passe. Il utilise la clause INSERT pour créer une nouvelle ligne avec ces détails et, en cas de succès, renvoie l'utilisateur nouvellement créé. Notez qu'avant de stocker le mot de passe, vous devez hachez-le en utilisant bcrypt. Ce n'est jamais une bonne idée de stocker les mots de passe sous forme de texte brut. Si des pirates avaient accès à votre base de données d'utilisateurs, ils pourraient facilement accéder à des informations sensibles.

Installez bcryptjs pour commencer à l'utiliser :

npm installer bcryptjs

Dans helper.js, importez bcryptjs :

constante bcrypt = exiger("bcryptjs")

En utilisant Bcryptjs, la base de données ne stocke que le mot de passe chiffré. Par conséquent, lors de la connexion, vous devrez comparer le mot de passe en clair donné par l'utilisateur et le mot de passe haché dans la base de données. Pour cela, vous pouvez utiliser la méthode de comparaison fournie par Bcryptjs.

Créez une fonction appelée matchPassword() :

constante matchPassword = asynchrone (mot de passe, hashPassword) => {
constante match = attendre bcrypt.compare (mot de passe, hashPassword);
revenir match
};

Il reçoit le mot de passe en clair et le hachage, puis utilise Bcrypt.compare() pour déterminer si le mot de passe fourni est correct. Si c'est le cas, il renvoie vrai sinon, il renvoie faux.

Ce sont toutes les fonctions que nous utiliserons pour interagir avec la base de données. Assurez-vous de tous les exporter à la fin :

module.exports = { emailExists, createUser, matchPassword } ;

Configurer Passeport

Passport est un middleware d'authentification Node qui fournit plus de 500 stratégies d'authentification telles que la connexion sociale, les jetons Web JSON (JWT) et l'authentification par e-mail. Nous utiliserons ce dernier que la stratégie passeport-local fournit.

Utilisez la commande suivante pour installer passeport et passeport-local :

passeport d'installation npm
npm installer passeport-local

Ensuite, configurez Passport pour connecter les utilisateurs existants et enregistrer de nouveaux utilisateurs.

Commencez par créer un nouveau fichier passeportConfig.js. Ensuite, importez la stratégie locale Passport et les fonctions d'assistance de base de données que vous venez de créer :

constante StratégieLocale = exiger("passeport-local");
constante { emailExists, createUser, matchPassword } = exiger("./assistant");

Dans le même fichier, ajoutez les éléments suivants pour configurer l'inscription des utilisateurs :

module.exports = (passeport) => {
passeport.use(
"inscription-locale",
Nouveau StratégieLocale(
{
usernameField: "e-mail",
passwordField: "mot de passe",
},
asynchrone (email, mot de passe, fait) => {
essayer {
constante userExists = attendre emailExiste (email)

si (l'utilisateur existe) {
revenir Fini(nul, faux);
}

constante utilisateur = attendre createUser (e-mail, mot de passe) ;
revenir Fini(nul, utilisateur);
} attraper (Erreur) {
fait (erreur);
}
}
)
);
}

Étant donné que passeport-local attend un nom d'utilisateur et un mot de passe, et que vous utilisez un e-mail, définissez le champ du nom d'utilisateur sur un e-mail. L'utilisateur ou plutôt la partie frontale de cette application enverra l'email et le mot de passe dans le corps de la requête. Cependant, vous n'avez pas besoin d'extraire les valeurs vous-même car Passport s'en chargera en arrière-plan.

Ce programme vérifie d'abord si l'e-mail est déjà pris en utilisant la fonction emailExists() de helper.js. Si l'e-mail n'existe pas dans la base de données, il crée un nouvel utilisateur avec la fonction createUser(). Enfin, il renvoie l'objet utilisateur.

Pour connecter les utilisateurs, ajoutez ce qui suit à passeportConfig.js :

module.exports = (passeport) => {
passeport.use(
"inscription-locale",
Nouveau StratégieLocale(
// S'inscrire
)
);
passeport.use(
"local-login",
Nouveau StratégieLocale(
{
usernameField: "e-mail",
passwordField: "mot de passe",
},
asynchrone (email, mot de passe, fait) => {
essayer {
constante utilisateur = attendre emailExists (email);
si (!utilisateur) revenir Fini(nul, faux);
constante estCorrespondance = attendre matchPassword (mot de passe, utilisateur.motdepasse);
si (!estMatch) revenir Fini(nul, faux);
revenir Fini(nul, {identifiant: identifiant d'utilisateur, e-mail: utilisateur.email});
} attraper (Erreur) {
revenir fait (erreur, faux);
}
}
)
);
};

Ici, le programme vérifie d'abord si l'e-mail est enregistré. Sinon, il renvoie faux. S'il trouve l'e-mail, il compare son mot de passe avec celui de la requête. Si les mots de passe correspondent, il connecte l'utilisateur et renvoie l'objet utilisateur.

La dernière étape consiste à créer les points de terminaison de l'API :

  • POST /auth/inscription
  • POST /auth/login

Ces deux points de terminaison recevront un e-mail et un mot de passe dans le corps de la demande. Ils incluront également les fonctions middleware d'authentification de passeport que nous venons de configurer.

Importez et configurez Passport dans un nouveau fichier nommé serveur.js:

constante passeport = exiger("passeport");
exiger(""./passportConfig")(passeport);

Ajoutez ensuite les routes suivantes :

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

Ces deux routes renvoient un objet JSON contenant l'utilisateur en cas de succès.

Vérifiez votre API à l'aide de tests unitaires

Vous pouvez utiliser Passport pour authentifier une application Node à l'aide d'une application PostgreSQL. Vous avez créé des points de terminaison d'API pour inscrire et connecter des utilisateurs.

Bien que vous puissiez utiliser des clients REST comme Postman pour tester le bon fonctionnement d'une API, l'écriture de tests unitaires est beaucoup plus simple. Les tests unitaires vous permettent de tester les différentes parties de votre application. De cette façon, même en cas de défaillance d'un point de terminaison, vous pouvez identifier le point de défaillance exact. L'un des outils que vous pouvez utiliser pour tester les applications Node est Jest.