JWT je docela jednoduchá metoda použitelné k autorizaci. Princip fungování asi nejlépe popíše samotný obrázek s diagramem:
Součástí vráceného tokenu mohou být jakákoliv data získaná při autorizaci na serveru, protože jsou vráceny zakódovaná. Data si takto můžete předávat v aplikaci dál. Každá zabezpečená routa může dostat do svého requestu dekódovaná data a dál s nimi pracovat
Opravdu jednoduchá implementace
Samotnou práci s JWT zajišťuje NPM balíček jsonwebtoken. Nejdůležitější je asi samotná funkce verifyToken jako Expressjs midleware funkce, ktará zajišťuje JWT autorizaci. Vše ostatni je jen obsluha jednotlivých rout…
// index.js
const express = require('express');
const bodyParser = require('body-parser');
const jwt = require('jsonwebtoken');
const jwtPassword = 'heslokterymsevsekryptuje';
const server = express();
server.use(bodyParser.json());
/**
* Tohle je midleware funkce, ktera zjistuje pritomnost a spravnost tokenu v kazem requestu.
* V pripade, ze je token OK, pak se provadi nasledno zpracovani.
* @param {Request} req - HTTP request
* @param {Response} res - HTTP response
* @param {Function} next - next function in processing
*/
function verifyToken(req, res, next) {
if (!req.body.token)
return res.status(403).json({
auth: false,
msg: 'missing token'
});
try {
const decode = jwt.verify(req.body.token, jwtPassword);
req.email = decode.email;
next();
} catch (error) {
return res.status(500).json({
auth: false,
msg: 'failed authenticate token'
});
}
}
/**
* POST /login
* body JSON s klici 'email' a 'password'
* Pokud je OK, vraci v odpovedi (JSON) s klicem 'token', ktery pak musi byt predavan v kazdem requestu
*/
server.post('/login', (req, res) => {
// TODO: naimplementuj vlastni logiku pro overovani, ktera bude vracet token
if (req.body.email === 'root@google.com' && req.body.password === 'supertruper') {
return res.status(200).json({
auth: true,
token: jwt.sign({ email: req.body.email }, jwtPassword, {
expiresIn: 86400
})
});
} else {
return res.status(401).json({
auth: false
});
}
});
/**
* Funkce pro ziskavani samotnych dat.
* Protoze vyuziva midleware funkco verifyToken, nevrati data bez tokenu :)
*/
server.post('/data', verifyToken, (req, res) => {
res.status(200).json({
user: req.email,
data: {
id: 44,
value: 'pepa'
}
});
});
/**
* Start HTTP serveru, ktery ma 2 routy:
* POST /login pro ziskani tokenu
* POST /data pro zasilani dat po autorizaci (se ziskanym tokenem)
*/
server.listen(process.env.PORT || 8080, () => {
console.log(`server running on http://localhost ${process.env.PORT || 8080}`);
});
POST /login – získání tokenu, kde v body je email a password
POST /data – zabezpečené načítání dat, kde v requestu musí být ‚token‘ získaný z /login a pak v odpovědi jsou požadovaná data.
Routa /data samozřejmě může fungovat i na metodě GET, ale pak by bylo potřeba přepsat autorizačni funkci midlewaru tak, aby token hledala například v hlavičce requestu. Nic složitého…
