În calitate de dezvoltator, este responsabilitatea dumneavoastră să protejați datele utilizatorilor prin autentificare. Puteți utiliza Passport.js pentru a autentifica utilizatorii într-o aplicație Node și Postgres.

Începeți prin a crea un server Node cu puncte finale pentru a înregistra, a vă conecta și a deconecta utilizatorii. Puteți lăsa Passport să se ocupe de autentificare pentru a restricționa accesul neautorizat la aplicația dvs.

Crearea unui tabel de utilizatori

Pentru autentificarea utilizatorului, veți folosi un e-mail și o parolă. Aceasta înseamnă că tabelul utilizatorilor trebuie să conțină un e-mail și un câmp de parolă. În promptul de comandă psql, creați o nouă bază de date numită nodeapp:

CREABAZĂ DE DATE nodeapp;

Apoi, creați un tabel pentru a stoca utilizatorii:

CREAMASAutilizatorii (
id INT GENERAT ÎNTOTDEAUNA CA CHEIE PRIMARĂ DE IDENTITATE,
e-mail CHAR(128),
parola CHAR(60)
);

Acest cod va crea un nou tabel care conține e-mail, parolă și un câmp ID generat automat.

Crearea unui Node Server

Node.js este un mediu de rulare JavaScript la nivelul serverului care ne permite să creăm rapid servere HTTP. Pentru a simplifica procesul de creare a serverului și a diferitelor rute HTTP, puteți utiliza Express, un cadru web Node.js.

Rulați această comandă pentru a crea un folder nou numit postgres-auth:

mkdir postgres-auth

Apoi, inițializați npm:

npm init -y

În cele din urmă, instalați Express:

npm install express

Acuma poți creați serverul web Node.

Într-un fișier nou numit index.js, adăugați următoarele:

const expres = cere("expres");
const aplicație = expres();
app.use (express.json());
app.use (express.urlencoded({ extins: Adevărat }));
app.listen(3000, () => consolă.log("Ascult pe port 3000"));

Rularea acestui cod va porni serverul și va înregistra următoarele în consolă:

Ascult pe portul 3000

Conectarea la PostgreSQL

La conectați-vă la PostgreSQL utilizare nod-postgres. node-postgres este un driver de conexiune care oferă o interfață între Node și Postgres.

Executați următoarele pentru a instala node-postrges prin npm:

npm install pg

După ce ați instalat biblioteca respectivă, creați un fișier nou numit db.js și conectați-l la baza de date:

const { Client } = cere("pg");
const { utilizator, gazdă, bază de date, parolă, port } = cere(""./dbConfig");

const client = nou Client({
utilizator,
gazdă,
Bază de date,
parola,
port,
});

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

Metoda client de la node-postgres preia detaliile bazei de date la care vă conectați. Acest program importă detaliile de conectare dintr-un fișier numit dbConfig. Prin urmare, creați acel fișier și adăugați următorul cod la el:

modul.exports = {
utilizator: "postgres",
gazdă: „localhost”,
baza de date: "nodeapp",
parola: "parola ta",
port: 5432,
};

Creați funcții de ajutor pentru baze de date

Este întotdeauna o practică bună să folosiți funcții individuale pentru a interacționa cu baza de date. Ele facilitează scrierea testelor unitare și îmbunătățesc reutilizarea. Pentru punctul final de înregistrare, trebuie să creați două funcții:

  1. Pentru a verifica dacă e-mailul este deja înregistrat.
  2. Pentru a crea utilizatorul.

Scopul este de a înregistra un utilizator numai dacă acesta nu există în baza de date.

Creați un fișier nou numit helper.js și importați clientul bazei de date din db.js:

const client = cere(""./db.js")

Apoi, adăugați o nouă funcție numită emailExists():

const emailExists = asincron (e-mail) => {
const date = așteaptă client.query("SELECT * FROM users WHERE email=$1", [
e-mail,
]);

dacă (data.rowCount == 0) întoarcerefals;
întoarcere date.rows[0];
};

Această funcție preia un e-mail și verifică dacă este deja utilizată. Face acest lucru folosind clauza SELECT care returnează un rând care are un câmp de e-mail care se potrivește cu valoarea furnizată de utilizatorul care se înregistrează. Dacă e-mailul nu există, se întoarce false.

Pentru a crea o funcție care creează utilizatorul, adăugați o funcție numită createUser() la helper.js:

const createUser = asincron (e-mail, parola) => {
const sare = așteaptă bcrypt.genSalt(10);
const hash = așteaptă bcrypt.hash (parolă, sare);

const date = așteaptă client.query(
„INSERT INTO useri (e-mail, parola) VALUES ($1, $2) RETURNARE ID-ul, e-mailul, parola",
[e-mail, hash]
);

dacă (data.rowCount == 0) întoarcerefals;
întoarcere date.rows[0];
};

Această funcție preia valorile de e-mail și parolă. Folosește clauza INSERT pentru a crea un nou rând cu aceste detalii și, dacă reușește, returnează utilizatorul nou creat. Rețineți că, înainte de a stoca parola, ar trebui hash-o folosind bcrypt. Nu este niciodată o idee bună să stocați parolele ca text simplu. Dacă hackerii au acces la baza de date cu utilizatori, ar putea accesa cu ușurință informații sensibile.

Instalați bcryptjs pentru a începe să-l utilizați:

npm instalează bcryptjs

În helper.js, importați bcryptjs:

const bcrypt = cere("bcryptjs")

Prin utilizarea Bcryptjs, baza de date stochează doar parola criptată. Prin urmare, în timpul autentificării, va trebui să comparați parola text simplu dată de utilizator și parola codificată din baza de date. Pentru aceasta, puteți utiliza metoda de comparare oferită de Bcryptjs.

Creați o funcție numită matchPassword():

const matchPassword = asincron (parolă, hashPassword) => {
const potrivire = așteaptă bcrypt.compare (parolă, hashPassword);
întoarcere Meci
};

Primește parola simplă și hash-ul și apoi folosește Bcrypt.compare() pentru a determina dacă parola furnizată este corectă. Dacă este, returnează adevărat, în caz contrar, returnează false.

Acestea sunt toate funcțiile pe care le vom folosi pentru a interacționa cu baza de date. Asigurați-vă că le exportați pe toate la sfârșit:

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

Configurați Passport

Passport este un middleware de autentificare Node care oferă peste 500 de strategii de autentificare, cum ar fi autentificarea socială, JSON Web Tokens (JWT) și autentificarea prin e-mail. Vom folosi acest din urmă pe care îl oferă strategia locală de pașapoarte.

Utilizați următoarea comandă pentru a instala pașaport și pașaport-local:

npm instalează pașaport
npm instalează pasaport-local

Apoi, configurați Passport pentru a vă conecta utilizatorii existenți și a înregistra noi utilizatori.

Începeți prin a crea un fișier nou passportConfig.js. Apoi, importați strategia locală Passport și funcțiile de ajutor pentru baze de date pe care tocmai le-ați creat:

const LocalStrategy = cere(„pașaport-local”);
const { emailExists, createUser, matchPassword } = cere("./ajutor");

În același fișier adăugați următoarele pentru a configura înregistrarea utilizatorului:

modul.exports = (pașaport) => {
pasaport.use(
"înregistrare locală",
nou LocalStrategy(
{
usernameField: „e-mail”,
passwordField: „parolă”,
},
asincron (e-mail, parola, terminat) => {
încerca {
const userExists = așteaptă emailExists (e-mail)

dacă (userExists) {
întoarcere Terminat(nul, fals);
}

const utilizator = așteaptă createUser (e-mail, parola);
întoarcere Terminat(nul, utilizator);
} captură (eroare) {
terminat (eroare);
}
}
)
);
}

Deoarece passport-local așteaptă un nume de utilizator și o parolă, iar dvs. utilizați un e-mail, setați câmpul nume de utilizator la un e-mail. Utilizatorul sau mai degrabă partea frontală a acestei aplicații va trimite e-mailul și parola în corpul solicitării. Cu toate acestea, nu trebuie să extrageți singur valorile, deoarece Passport se va ocupa de asta în fundal.

Acest program verifică mai întâi dacă e-mailul este deja preluat folosind funcția emailExists() de la helper.js. Dacă e-mailul nu există în baza de date, acesta creează un nou utilizator cu funcția createUser(). În cele din urmă, returnează obiectul utilizator.

Pentru a vă autentifica utilizatorii, adăugați următoarele la passportConfig.js:

modul.exports = (pașaport) => {
pasaport.use(
"înregistrare locală",
nou LocalStrategy(
// Inscrie-te
)
);
pasaport.use(
"local-login",
nou LocalStrategy(
{
usernameField: „e-mail”,
passwordField: „parolă”,
},
asincron (e-mail, parola, terminat) => {
încerca {
const utilizator = așteaptă emailExists (email);
dacă (!utilizator) întoarcere Terminat(nul, fals);
const isMatch = așteaptă matchPassword (parolă, utilizator.parolă);
dacă (!isMatch) întoarcere Terminat(nul, fals);
întoarcere Terminat(nul, {id: numele de utilizator, e-mail: user.email});
} captură (eroare) {
întoarcere terminat (eroare, fals);
}
}
)
);
};

Aici, programul verifică mai întâi dacă e-mailul este înregistrat. Dacă nu, se întoarce false. Dacă găsește e-mailul, își compară parola cu cea din cerere. Dacă parolele se potrivesc, se conectează utilizatorul și returnează obiectul utilizator.

Pasul final este crearea punctelor finale API:

  • POST /auth/signup
  • POST /auth/login

Ambele puncte finale vor primi un e-mail și o parolă în corpul solicitării. Ele vor include, de asemenea, funcțiile middleware de autentificare a pașaportului pe care tocmai le-am configurat.

Importați și configurați Passport într-un fișier nou numit server.js:

const pasaport = cere("pașaport");
cere(""./passportConfig")(paşaport);

Apoi, adăugați următoarele rute:

app.post(
"/auth/Inscrie-te",
passport.authenticate ("înregistrare locală", { sesiune: fals }),
(req, res, next) => {
res.json({
utilizator: req.user,
});
}
);
app.post(
"/auth/Autentificare",
passport.authenticate("local-login", { sesiune: fals }),
(req, res, next) => {
res.json({ utilizator: utilizator solicitat });
}
);

Ambele rute returnează un obiect JSON care conține utilizatorul dacă au succes.

Verificați-vă API-ul folosind teste unitare

Puteți utiliza Passport pentru a autentifica o aplicație Node folosind o aplicație PostgreSQL. Ați creat puncte finale API pentru a vă înscrie și a conecta utilizatorii.

Deși puteți utiliza clienții REST precum Postman pentru a testa cât de bine funcționează un API, scrierea testelor unitare este mult mai simplă. Testele unitare vă permit să testați părțile individuale ale aplicației dvs. În acest fel, chiar dacă un punct final eșuează, puteți identifica punctul exact de eșec. Unul dintre instrumentele pe care le puteți utiliza pentru a testa aplicațiile Node este Jest.