Cum să autentificați și să autorizați utilizatorul folosind JWT în NodeJS

Autentificarea și autorizarea este conceptul de bază al securității computerului. Vă folosiți acreditările (cum ar fi un nume de utilizator și o parolă) pentru a vă dovedi identitatea și pentru a vă identifica ca utilizator înregistrat și apoi pentru a obține privilegii suplimentare.

Acest lucru se aplică și atunci când vă conectați la serviciile online folosind conturile dvs. Facebook sau Google.

În acest articol, vom construi un API Nodejs cu autentificare JWT (JSON Web Tokens). Instrumentele pe care le vom folosi în acest tutorial sunt:

  • Expressjs
  • Baza de date MongoDB
  • Mangustă
  • Dotenv
  • Bcryptjs
  • Jsonwebtoken

Autentificare vs. Autorizare

Ce este autentificarea?

Autentificarea este procesul de identificare a utilizatorilor prin dobândirea de acreditări precum e-mail, parolă și token-uri. Acreditările date sunt comparate cu acreditările utilizatorului înregistrat, care sunt disponibile în fișierul sistemului informatic local sau în orice baze de date. Dacă acreditările date se potrivesc cu datele disponibile în baza de date, procesul de autentificare este finalizat și utilizatorului i se permite să acceseze resursele.

Ce este Autorizarea?

Autorizarea are loc după autentificare. Fiecare autorizație trebuie să aibă un proces de autentificare. Este procesul de a permite utilizatorilor să acceseze resurse de la sisteme sau un site web. În acest tutorial, vom autoriza utilizatorii conectați să acceseze datele utilizatorului. Dacă utilizatorul nu este autentificat, nu va putea folosi accesul la date.

Cele mai bune exemple de autorizare sunt platformele de social media precum Facebook și Twitter. Nu puteți accesa conținutul rețelelor sociale fără a avea un cont.

Un alt exemplu de autorizare este conținutul bazat pe abonament, autentificarea dvs. se poate face prin autentificarea pe site, dar nu veți fi autorizat să accesați conținutul până când nu vă abonați.

Condiție prealabilă

Înainte de a merge mai departe, presupun că aveți o înțelegere de bază a Javascript și MongoDB și cunoștințe bune despre Nodejs.

Asigurați-vă că ați instalat node și npm pe mașina dvs. locală. Pentru a verifica dacă node și npm sunt instalate pe computer, deschideți promptul de comandă și tastați node -v și npm -v. Acest lucru ar trebui să arate următorul rezultat.

Versiunile tale pot diferi de ale mele. NPM este descărcat automat cu nodul. Dacă nu l-ați descărcat încă, descărcați-l din Site-ul web NodeJS.

Veți avea nevoie de un IDE (mediu de dezvoltare integrat) pentru a scrie cod. În acest tutorial, folosesc editorul de cod VS. Dacă mai ai unul, îl poți folosi și pe acesta. Dacă nu aveți niciun IDE instalat pe computer, îl puteți descărca de pe Site-ul web Visual Studio. Descărcați-l pe baza sistemului dvs. local.

  17 Setări ale camerei pe care ar trebui să le modificați sau să le dezactivați întotdeauna

Stabilirea proiectului

Creați un nume de folder nodeapi oriunde pe computerul local, apoi deschideți-l cu vs-code. Deschideți terminalul vs-code și apoi inițializați managerul de pachete de noduri tastând.

npm init -y

Asigurați-vă că vă aflați în directorul nodeapi.

Comanda de mai sus va crea un fișier package.json care conține toate dependențele pe care le vom folosi în acest proiect.

Acum vom descărca toate pachetele menționate mai sus, acum tastați și introduceți-le în terminal.

npm install express dotenv jsonwebtoken mongoose bcryptjs

Acum, veți avea fișiere și foldere, așa cum se arată mai jos.

Crearea serverului și conectarea bazei de date

Acum creați un fișier numit index.js și un folder numit config. În config, creați două fișiere numite conn.js pentru a vă conecta la baza de date și config.env pentru a declara variabilele de mediu. Scrieți codul dat mai jos în fișierele respective.

index.js

const express = require('express');
const dotenv = require('dotenv');

//Configure dotenv files above using any other library and files
dotenv.config({path:'./config/config.env'}); 

//Creating an app from express
const app = express();

//Using express.json to get request of json data
app.use(express.json());



//listening to the server
app.listen(process.env.PORT,()=>{
    console.log(`Server is listening at ${process.env.PORT}`);
})

Dacă utilizați dotenv, configurați-l în fișierul index.js înainte de a apela alte fișiere care utilizează variabile de mediu.

conn.js

const mongoose = require('mongoose');

mongoose.connect(process.env.URI, 
    { useNewUrlParser: true,
     useUnifiedTopology: true })
    .then((data) => {
        console.log(`Database connected to ${data.connection.host}`)
})

config.env

URI = 'mongodb+srv://ghulamrabbani883:[email protected]/?retryWrites=true&w=majority'
PORT = 5000

Folosesc mongo-DB Atlas URI, puteți folosi și localhost.

Crearea de modele și rute

Modelul este un aspect al datelor dvs. în baza de date Mongo-DB și va fi stocat ca document JSON. Pentru a crea un model, vom folosi schema mangoose.

Rutarea se referă la modul în care o aplicație răspunde la solicitările clientului. Vom folosi funcția de router expres pentru a crea rute.

Metodele de rutare iau de obicei două argumente. Primul este ruta, iar al doilea este funcția de apel invers pentru a defini ce ar face această rută la cererea clientului.

De asemenea, este nevoie de un al treilea argument ca funcție middleware atunci când este necesar, ca în procesul de autentificare. Pe măsură ce construim API-ul autentificat, vom folosi și funcția middleware pentru a autoriza și a autentifica utilizatorii.

Acum vom crea două foldere numite rute și modele. În interiorul rutelor, creați un nume de fișier userRoute.js și în folderul modele, creați un nume de fișier userModel.js. După crearea fișierelor, scrieți următorul cod în fișierele respective.

userModel.js

const mongoose = require('mongoose');

//Creating Schema using mongoose
const userSchema = new mongoose.Schema({
    name: {
        type:String,
        required:true,
        minLength:[4,'Name should be minimum of 4 characters']
    },
    email:{
        type:String,
        required:true,
        unique:true,
    },
    password:{
        type:String,
        required:true,
        minLength:[8,'Password should be minimum of 8 characters']
    },
    token:{
        type:String
    }
})

//Creating models
const userModel = mongoose.model('user',userSchema);
module.exports = userModel;

userRoute.js

const express = require('express');
//Creating express router
const route = express.Router();
//Importing userModel
const userModel = require('../models/userModel');

//Creating register route
route.post('/register',(req,res)=>{

})
//Creating login routes
route.post('/login',(req,res)=>{

})

//Creating user routes to fetch users data
route.get('/user',(req,res)=>{

})

Implementarea funcționalității rutei și crearea de jetoane JWT

Ce este JWT?

Jetoanele web JSON (JWT) este o bibliotecă javascript care creează și verifică simboluri. Este un standard deschis folosit pentru a partaja informații între două părți – un client și un server. Vom folosi două funcții ale JWT. Prima funcție este semn pentru a crea un nou token, iar a doua funcție este de verificare pentru a verifica simbolul.

  13 cele mai bune teme multifuncționale pentru a crea un site web WordPress unic

Ce este bcryptjs?

Bcryptjs este o funcție de hashing creată de Niels Provos și David Mazières. Utilizează un algoritm hash pentru a hash parola. Are două funcții cele mai comune pe care le vom folosi în acest proiect. Prima funcție bcryptjs este hash pentru a genera valoarea hash, iar a doua funcție este funcția de comparare pentru a compara parolele.

Implementați funcționalitatea rutei

Funcția de apel invers în rutare ia trei argumente, cerere, răspuns și următoarea funcție. Următorul argument este opțional; dați asta numai când aveți nevoie de asta. Aceste argumente ar trebui să fie în cerere, răspuns și următoarea ordine. Acum modificați fișierele userRoute.js, config.env și index.js cu următoarele coduri.

userRoute.js

//Requiring all the necessary files and libraries
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');

//Creating express router
const route = express.Router();
//Importing userModel
const userModel = require('../models/userModel');

//Creating register route
route.post("/register", async (req, res) => {

    try {
        const { name, email, password } = req.body;
        //Check emptyness of the incoming data
        if (!name || !email || !password) {
            return res.json({ message: 'Please enter all the details' })
        }

        //Check if the user already exist or not
        const userExist = await userModel.findOne({ email: req.body.email });
        if (userExist) {
            return res.json({ message: 'User already exist with the given emailId' })
        }
        //Hash the password
        const salt = await bcrypt.genSalt(10);
        const hashPassword = await bcrypt.hash(req.body.password, salt);
        req.body.password = hashPassword;
        const user = new userModel(req.body);
        await user.save();
        const token = await jwt.sign({ id: user._id }, process.env.SECRET_KEY, {
            expiresIn: process.env.JWT_EXPIRE,
        });
        return res.cookie({ 'token': token }).json({ success: true, message: 'User registered successfully', data: user })
    } catch (error) {
        return res.json({ error: error });
    }

})
//Creating login routes
route.post('/login', async (req, res) => {
    try {
        const { email, password } = req.body;
        //Check emptyness of the incoming data
        if (!email || !password) {
            return res.json({ message: 'Please enter all the details' })
        }
        //Check if the user already exist or not
        const userExist = await userModel.findOne({email:req.body.email});
        if(!userExist){
            return res.json({message:'Wrong credentials'})
        }
        //Check password match
        const isPasswordMatched = await bcrypt.compare(password,userExist.password);
        if(!isPasswordMatched){
            return res.json({message:'Wrong credentials pass'});
        }
        const token = await jwt.sign({ id: userExist._id }, process.env.SECRET_KEY, {
            expiresIn: process.env.JWT_EXPIRE,
        });
        return res.cookie({"token":token}).json({success:true,message:'LoggedIn Successfully'})
    } catch (error) {
        return res.json({ error: error });
    }

})

//Creating user routes to fetch users data
route.get('/user', async (req, res) => {
    try {
        const user  = await userModel.find();
        if(!user){
            return res.json({message:'No user found'})
        }
        return res.json({user:user})
    } catch (error) {
        return res.json({ error: error });  
    }
})

module.exports = route;

Dacă utilizați funcția Async, utilizați blocul try-catch, altfel va genera o eroare de respingere a promisiunii netratată.

config.env

URI = 'mongodb+srv://ghulamrabbani883:[email protected]/?retryWrites=true&w=majority'
PORT = 5000
SECRET_KEY = KGGK>HKHVHJVKBKJKJBKBKHKBMKHB
JWT_EXPIRE = 2d

index.js

const express = require('express');
const dotenv = require('dotenv');

//Configure dotenv files above using any other library and files
dotenv.config({path:'./config/config.env'}); 
require('./config/conn');
//Creating an app from express
const app = express();
const route = require('./routes/userRoute');

//Using express.json to get request of json data
app.use(express.json());
//Using routes

app.use('/api', route);

//listening to the server
app.listen(process.env.PORT,()=>{
    console.log(`Server is listening at ${process.env.PORT}`);
})

Crearea middleware pentru autentificarea utilizatorului

Ce este middleware-ul?

Middleware-ul este o funcție care are acces la cerere, la obiectul răspuns și la următoarea funcție din ciclul cerere-răspuns. Următoarea funcție este invocată când execuția funcției este finalizată. După cum am menționat mai sus, utilizați next() când trebuie să executați o altă funcție de apel invers sau o funcție middleware.

  14 aplicații iPad pentru a rămâne organizat de-a lungul zilei [2023]

Acum creați un folder numit middleware și în interiorul acestuia, creați un nume de fișier ca auth.js și scrieți următorul cod.

auth.js

const userModel = require('../models/userModel');
const jwt = require('jsonwebtoken');
const isAuthenticated = async (req,res,next)=>{
    try {
        const {token} = req.cookies;
        if(!token){
            return next('Please login to access the data');
        }
        const verify = await jwt.verify(token,process.env.SECRET_KEY);
        req.user = await userModel.findById(verify.id);
        next();
    } catch (error) {
       return next(error); 
    }
}

module.exports = isAuthenticated;

Acum instalați biblioteca cookie-parser pentru a configura cookieParser-ul în aplicația dvs. cookieParser vă ajută să accesați simbolul stocat în cookie. Dacă nu aveți cookieParser configurat în aplicația nodejs, nu veți putea accesa cookie-urile din anteturile obiectului de solicitare. Acum, scrieți în terminal pentru a descărca cookie-parser.

npm i cookie-parser

Acum, aveți instalat un cookieParser. Configurați aplicația dvs. modificând fișierul index.js și adăugați middleware la ruta „/user/”.

fișierul index.js

const cookieParser = require('cookie-parser');
const express = require('express');
const dotenv = require('dotenv');

//Configure dotenv files above using any other library and files
dotenv.config({path:'./config/config.env'}); 
require('./config/conn');
//Creating an app from express
const app = express();
const route = require('./routes/userRoute');

//Using express.json to get request of json data
app.use(express.json());
//Configuring cookie-parser
app.use(cookieParser()); 

//Using routes
app.use('/api', route);

//listening to the server
app.listen(process.env.PORT,()=>{
    console.log(`Server is listening at ${process.env.PORT}`);
})

userRoute.js

//Requiring all the necessary files and libraries
const express = require('express');
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const isAuthenticated = require('../middleware/auth');

//Creating express router
const route = express.Router();
//Importing userModel
const userModel = require('../models/userModel');

//Creating user routes to fetch users data
route.get('/user', isAuthenticated, async (req, res) => {
    try {
        const user = await userModel.find();
        if (!user) {
            return res.json({ message: 'No user found' })
        }
        return res.json({ user: user })
    } catch (error) {
        return res.json({ error: error });
    }
})

module.exports = route;

Ruta „/utilizator” poate fi accesibilă numai atunci când utilizatorul este autentificat.

Verificarea API-urilor pe POSTMAN

Înainte de a verifica API-urile, trebuie să modificați fișierul package.json. Adăugați următoarele linii de cod.

"scripts": {
    "test": "echo "Error: no test specified" && exit 1",
    "start": "node index.js",
    "dev": "nodemon index.js"
  },

Puteți porni serverul tastând npm start, dar acesta va rula o singură dată. Pentru a menține serverul să funcționeze în timp ce schimbați fișierele, veți avea nevoie de nodemon. Descărcați-l tastând în terminal

npm install -g nodemon

-g flag va descărca nodemonul la nivel global pe sistemul dumneavoastră local. Nu trebuie să-l descărcați din nou și din nou pentru fiecare proiect nou.

Pentru a rula serverul, tastați npm run dev în terminal. Veți obține următorul rezultat.

În cele din urmă, codul dvs. este completat și serverul funcționează corect, mergeți la poștaș și verificați dacă funcționează.

Ce este POSTMAN?

POSTMAN este un instrument software pentru proiectarea, construirea, dezvoltarea și testarea API-urilor.

Dacă nu ați descărcat poștașul pe computer, descărcați-l de pe site-ul poștașului.

Acum deschideți poștașul și creați un nume de colecție nodeAPItest, iar în interiorul acestuia, creați trei solicitări: înregistrare, autentificare și utilizator. Ar trebui să aveți următoarele fișiere.

Când trimiteți date JSON către „localhost:5000/api/register”, veți obține următorul rezultat.

Deoarece creăm și salvăm token-uri în cookie-uri și în timpul înregistrării, puteți avea detalii despre utilizator atunci când solicitați ruta „localhost:5000/api/user”. Puteti verifica restul cererilor pe POTASAL.

Dacă doriți codul complet, îl puteți obține de la mine cont github.

Concluzie

În acest tutorial, am învățat cum să aplicăm autentificarea la API-ul NodeJS folosind jetoane JWT. De asemenea, am autorizat utilizatorii să acceseze datele utilizatorului.

CODARE FERICITĂ!