Autentizace a autorizace je základním konceptem počítačové bezpečnosti. Své přihlašovací údaje (jako je uživatelské jméno a heslo) používáte k prokázání své identity a identifikaci jako registrovaného uživatele a poté k získání dalších oprávnění.
To platí také v případě, že se přihlásíte do online služeb pomocí účtu Facebook nebo Google.
V tomto článku se chystáme vytvořit Nodejs API s autentizací JWT (JSON Web Tokens). Nástroje, které budeme v tomto tutoriálu používat, jsou:
- Expressjs
- databáze MongoDB
- Mangusta
- Dotenv
- Bcryptjs
- Jsonwebtoken
Table of Contents
Autentizace vs. Povolení
Co je autentizace?
Autentizace je proces identifikace uživatelů získáním přihlašovacích údajů, jako je e-mail, heslo a tokeny. Uvedené přihlašovací údaje jsou porovnávány s přihlašovacími údaji registrovaného uživatele, které jsou k dispozici v souboru lokálního počítačového systému nebo jakýchkoli databází. Pokud se daná pověření shodují s dostupnými údaji v databázi, proces ověřování je dokončen a uživateli je povolen přístup ke zdrojům.
Co je autorizace?
Autorizace probíhá po ověření. Každá autorizace musí mít autentizační proces. Je to proces umožňující uživatelům přístup ke zdrojům ze systémů nebo webových stránek. V tomto tutoriálu budeme autorizovat přihlášené uživatele k přístupu k datům uživatele. Pokud uživatel není přihlášen, nebude mít přístup k datům.
Nejlepšími příklady autorizace jsou platformy sociálních médií jako Facebook a Twitter. Bez účtu nemáte přístup k obsahu sociálních sítí.
Dalším příkladem autorizace je obsah založený na předplatném, vaše ověření lze provést přihlášením na webovou stránku, ale nebudete mít oprávnění k přístupu k obsahu, dokud se nepřihlásíte k odběru.
Předpoklad
Než se pohnete vpřed, předpokládám, že máte základní znalosti Javascriptu a MongoDB a dobré znalosti Nodejs.
Ujistěte se, že jste na místní počítač nainstalovali node a npm. Chcete-li zkontrolovat, zda jsou na vašem počítači nainstalovány node a npm, otevřete příkazový řádek a zadejte node -v a npm -v. To by mělo ukázat následující výsledek.
Vaše verze se mohou lišit od mých. NPM se automaticky stáhne s uzlem. Pokud jste si ji ještě nestáhli, stáhněte si ji z Web NodeJS.
K psaní kódu budete potřebovat IDE (Integrované vývojové prostředí). V tomto tutoriálu používám editor kódu VS. Pokud máte jinou, můžete ji také použít. Pokud nemáte na svém počítači nainstalované žádné IDE, můžete si jej stáhnout z Web Visual Studio. Stáhněte si ji na základě vašeho místního systému.
Nastavení projektu
Vytvořte složku s názvem nodeapi kdekoli v místním počítači a poté ji otevřete pomocí vs-code. Otevřete terminál vs-code a poté inicializujte správce balíčků uzlů zadáním.
npm init -y
Ujistěte se, že jste v adresáři nodeapi.
Výše uvedený příkaz vytvoří soubor package.json, který obsahuje všechny závislosti, které budeme v tomto projektu používat.
Nyní stáhneme všechny výše zmíněné balíčky, nyní je zadejte a zadejte do terminálu.
npm install express dotenv jsonwebtoken mongoose bcryptjs
Nyní budete mít soubory a složky, jak je znázorněno níže.
Vytvoření serveru a připojení databáze
Nyní vytvořte soubor s názvem index.js a složku s názvem config. Uvnitř config vytvořte dva soubory s názvem conn.js pro připojení k databázi a config.env pro deklaraci proměnných prostředí. Níže uvedený kód napište do příslušných souborů.
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}`); })
Pokud používáte dotenv, nakonfigurujte jej v souboru index.js před voláním dalších souborů, které používají proměnné prostředí.
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
Používám mongo-DB Atlas URI, můžete také použít localhost.
Vytváření modelů a tras
Model je rozložení vašich dat v databázi Mongo-DB a bude uloženo jako dokument JSON. K vytvoření modelu použijeme schéma mongoose.
Směrování se týká toho, jak aplikace reaguje na požadavky klientů. K vytváření tras použijeme funkci expresního routeru.
Metody směrování obvykle používají dva argumenty. První je trasa a druhá je funkce zpětného volání, která definuje, co by tato trasa udělala na žádost klienta.
V případě potřeby bere také třetí argument jako funkci middlewaru, například v procesu ověřování. Při vytváření autentizovaného API budeme také používat funkci middlewaru k autorizaci a ověřování uživatelů.
Nyní vytvoříme dvě složky s názvem trasy a modely. Uvnitř tras vytvořte název souboru userRoute.js a uvnitř složky modelů vytvořte název souboru userModel.js. Po vytvoření souborů zapište do příslušných souborů následující kód.
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)=>{ })
Implementace funkčnosti trasy a vytváření tokenů JWT
Co je JWT?
JSON webové tokeny (JWT) je javascriptová knihovna, která vytváří a ověřuje tokeny. Jedná se o otevřený standard používaný ke sdílení informací mezi dvěma stranami – klientem a serverem. Využijeme dvě funkce JWT. První funkcí je podepsat pro vytvoření nového tokenu a druhou funkcí je ověření pro ověření tokenu.
Co je bcryptjs?
Bcryptjs je hašovací funkce vytvořená Nielsem Provosem a Davidem Mazièresem. K hašování hesla používá hašovací algoritmus. Má dvě nejběžnější funkce, které budeme v tomto projektu používat. První funkce bcryptjs je hash pro generování hodnoty hash a druhá funkce je funkce porovnání pro porovnání hesel.
Implementujte funkcionalitu trasy
Funkce zpětného volání ve směrování přebírá tři argumenty, požadavek, odpověď a další funkci. Další argument je volitelný; předávejte to, jen když to potřebujete. Tyto argumenty by měly být v požadavku, odpovědi a dalším pořadí. Nyní upravte soubory userRoute.js, config.env a index.js pomocí následujících kódů.
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;
Pokud používáte funkci Async, použijte blok try-catch, jinak vyvolá neošetřenou chybu odmítnutí slibu.
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}`); })
Vytváření middlewaru pro ověření uživatele
Co je middleware?
Middleware je funkce, která má přístup k požadavku, objektu odezvy a další funkci v cyklu požadavek-odpověď. Další funkce je vyvolána po dokončení provádění funkce. Jak jsem zmínil výše, použijte next(), když musíte provést jinou funkci zpětného volání nebo middlewarovou funkci.
Nyní vytvořte složku s názvem middleware a v ní vytvořte název souboru jako auth.js a napište následující kód.
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;
Nyní nainstalujte knihovnu cookie-parser, abyste nakonfigurovali cookieParser ve vaší aplikaci. cookieParser vám pomůže získat přístup k tokenu uloženému v cookie. Pokud nemáte v aplikaci nodejs nakonfigurovaný cookieParser, nebudete mít přístup k souborům cookie ze záhlaví objektu požadavku. Nyní napište do terminálu a stáhněte si analyzátor souborů cookie.
npm i cookie-parser
Nyní máte nainstalovaný cookieParser. Nakonfigurujte svou aplikaci úpravou souboru index.js a přidáním middlewaru do trasy „/user/“.
soubor 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;
Cesta „/user“ je přístupná pouze tehdy, když je uživatel přihlášen.
Kontrola API na POSTMAN
Než zkontrolujete rozhraní API, musíte upravit soubor package.json. Přidejte následující řádky kódu.
"scripts": { "test": "echo "Error: no test specified" && exit 1", "start": "node index.js", "dev": "nodemon index.js" },
Server můžete spustit zadáním npm start, ale spustí se pouze jednou. Chcete-li udržet váš server v chodu při změně souborů, budete potřebovat nodemon. Stáhněte si jej zadáním do terminálu
npm install -g nodemon
-g příznak stáhne uzlu globálně na váš lokální systém. Nemusíte jej stahovat znovu a znovu pro každý nový projekt.
Chcete-li spustit server, zadejte do terminálu npm run dev. Získáte následující výsledek.
Nakonec je váš kód dokončen a server běží správně, přejděte k pošťákovi a zkontrolujte, zda funguje.
Co je POSTMAN?
POSTMAN je softwarový nástroj pro návrh, sestavení, vývoj a testování API.
Pokud jste si pošťáka nestáhli do počítače, stáhněte si ho z web pošťáka.
Nyní otevřete pošťáka a vytvořte název kolekce nodeAPItest a v něm vytvořte tři požadavky: registraci, přihlášení a uživatele. Měli byste mít následující soubory.
Když odešlete data JSON na „localhost:5000/api/register“, získáte následující výsledek.
Vzhledem k tomu, že vytváříme a ukládáme tokeny do souborů cookie také během registrace, můžete mít údaje o uživateli, když požadujete cestu „localhost:5000/api/user“. Zbytek požadavků si můžete zkontrolovat na POSTMAN.
Pokud chcete úplný kód, můžete ho získat od mého účet github.
Závěr
V tomto tutoriálu jsme se naučili, jak aplikovat ověřování na NodeJS API pomocí tokenů JWT. Také jsme povolili uživatelům přístup k uživatelským údajům.
ŠŤASTNÉ KÓDOVÁNÍ!