From 6757f6669ce20618ac3e97899e13828fe809f443 Mon Sep 17 00:00:00 2001 From: Lucas Serrey Date: Wed, 11 Dec 2019 16:09:05 -0300 Subject: [PATCH] Agregada generacion de jwt --- package-lock.json | 91 ++++++++++++++++++++++++++++++++++++++ package.json | 1 + server/config/config.js | 11 +++++ server/middlewares/auth.js | 54 ++++++++++++++++++++++ server/models/usuario.js | 9 ++++ server/routes/index.js | 7 +++ server/routes/login.js | 56 +++++++++++++++++++++++ server/routes/usuario.js | 15 ++++--- server/server.js | 15 ++++--- 9 files changed, 247 insertions(+), 12 deletions(-) create mode 100644 server/middlewares/auth.js create mode 100644 server/routes/index.js create mode 100644 server/routes/login.js diff --git a/package-lock.json b/package-lock.json index 3de3e79..1493edb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -92,6 +92,11 @@ "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.3.tgz", "integrity": "sha512-TdiJxMVnodVS7r0BdL42y/pqC9cL2iKynVwA0Ho3qbsQYr428veL3l7BQyuqiw+Q5SqqoT0m4srSY/BlZ9AxXg==" }, + "buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha1-+OcRMvf/5uAaXJaXpMbz5I1cyBk=" + }, "bytes": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", @@ -178,6 +183,14 @@ "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=" }, + "ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "requires": { + "safe-buffer": "^5.0.1" + } + }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -370,6 +383,49 @@ "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" }, + "jsonwebtoken": { + "version": "8.5.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-8.5.1.tgz", + "integrity": "sha512-XjwVfRS6jTMsqYs0EsuJ4LGxXV14zQybNd4L2r0UvbVnSF9Af8x7p5MzbJ90Ioz/9TI41/hTCvznF/loiSzn8w==", + "requires": { + "jws": "^3.2.2", + "lodash.includes": "^4.3.0", + "lodash.isboolean": "^3.0.3", + "lodash.isinteger": "^4.0.4", + "lodash.isnumber": "^3.0.3", + "lodash.isplainobject": "^4.0.6", + "lodash.isstring": "^4.0.1", + "lodash.once": "^4.0.0", + "ms": "^2.1.1", + "semver": "^5.6.0" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + } + } + }, + "jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "requires": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "requires": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "kareem": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz", @@ -385,6 +441,41 @@ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk=" }, + "lodash.includes": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/lodash.includes/-/lodash.includes-4.3.0.tgz", + "integrity": "sha1-YLuYqHy5I8aMoeUTJUgzFISfVT8=" + }, + "lodash.isboolean": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isboolean/-/lodash.isboolean-3.0.3.tgz", + "integrity": "sha1-bC4XHbKiV82WgC/UOwGyDV9YcPY=" + }, + "lodash.isinteger": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/lodash.isinteger/-/lodash.isinteger-4.0.4.tgz", + "integrity": "sha1-YZwK89A/iwTDH1iChAt3sRzWg0M=" + }, + "lodash.isnumber": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz", + "integrity": "sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=" + }, + "lodash.isplainobject": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz", + "integrity": "sha1-fFJqUtibRcRcxpC4gWO+BJf1UMs=" + }, + "lodash.isstring": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/lodash.isstring/-/lodash.isstring-4.0.1.tgz", + "integrity": "sha1-1SfftUVuynzJu5XV2ur4i6VKVFE=" + }, + "lodash.once": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz", + "integrity": "sha1-DdOXEhPHxW34gJd9UEyI+0cal6w=" + }, "media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", diff --git a/package.json b/package.json index c54bac9..50c827e 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "bcrypt": "^3.0.7", "body-parser": "^1.19.0", "express": "^4.17.1", + "jsonwebtoken": "^8.5.1", "mongoose": "^5.7.14", "mongoose-unique-validator": "^2.0.3", "underscore": "^1.9.1" diff --git a/server/config/config.js b/server/config/config.js index 9781b67..e6b7eb2 100644 --- a/server/config/config.js +++ b/server/config/config.js @@ -8,6 +8,17 @@ process.env.PORT = process.env.PORT || 3000 // ========================= process.env.NODE_ENV = process.env.NODE_ENV || 'dev'; +// ========================= +// VENCIMIENTO DEL TOKEN +// ========================= +process.env.TOKEN_EXPIRE = 60 * 60 * 24 * 30; + +// ========================= +// SEED +// ========================= +process.env.SEED = process.env.SEED || 'el-secret-local'; + + // ========================= // Base de Datos // ========================= diff --git a/server/middlewares/auth.js b/server/middlewares/auth.js new file mode 100644 index 0000000..9b12ac9 --- /dev/null +++ b/server/middlewares/auth.js @@ -0,0 +1,54 @@ +const jwt = require('jsonwebtoken'); + +// ========================= +// Verifica Token +// ========================= +let verificaToken = (req, res, next) => { + + let token = req.get('token'); + + jwt.verify(token, process.env.SEED, (err, decoded) => { + + if (err) { + return res.status(401).json({ + ok: false, + err: { + message: 'Token no válido' + } + }); + } + + req.usuario = decoded.usuario; + next(); + + }); +}; + +// ========================= +// Verifica AdminRole +// ========================= +let verificaAdminRole = (req, res, next) => { + + usuario = req.usuario; + + if(usuario.role != 'ADMIN_ROLE'){ + + res.json({ + ok: false, + err: { + message: 'Debe ser administrador' + } + }); + } + else{ + + next(); + } + +}; + + +module.exports = { + verificaToken, + verificaAdminRole +} diff --git a/server/models/usuario.js b/server/models/usuario.js index 903f388..fbc68ad 100644 --- a/server/models/usuario.js +++ b/server/models/usuario.js @@ -43,6 +43,15 @@ let usuarioSchema = new Schema({ } }); +// Excluir atributos +usuarioSchema.methods.toJSON = function () { + + let userObject = this.toObject(); + delete userObject.password; + delete userObject.__v; + return userObject; +} + usuarioSchema.plugin( uniqueValidator, { message: '{PATH} debe ser unico' }); diff --git a/server/routes/index.js b/server/routes/index.js new file mode 100644 index 0000000..c3eea89 --- /dev/null +++ b/server/routes/index.js @@ -0,0 +1,7 @@ +const express = require('express'); +const app = express(); + +app.use(require('./usuario')); +app.use(require('./login')); + +module.exports = app; diff --git a/server/routes/login.js b/server/routes/login.js new file mode 100644 index 0000000..8d7e73c --- /dev/null +++ b/server/routes/login.js @@ -0,0 +1,56 @@ +const express = require('express'); +const bcrypt = require('bcrypt'); +const jwt = require('jsonwebtoken'); + +const Usuario = require('../models/usuario'); + +const app = express(); + +app.post('/login', (req,res) => { + + let body = req.body; + + Usuario.findOne({email: body.email}, (err, usuarioDB) => { + + if (err) { + return res.status(500).json({ + ok: false, + err + }); + } + + if(!usuarioDB){ + return res.status(400).json({ + ok: false, + err: { + message: '(Usuario) o contraseña incorrectos' + } + }); + } + + if( !bcrypt.compareSync( body.password, usuarioDB.password) ){ + return res.status(400).json({ + ok: false, + err: { + message: 'Usuario o (contraseña) incorrectos' + } + }); + } + + let token = jwt.sign({ + usuario: usuarioDB + }, process.env.SEED, { expiresIn: process.env.TOKEN_EXPIRE }) // 30 dias + + res.json({ + ok: true, + usuario: usuarioDB, + token + }); + }); + + + +}); + + +module.exports = app; diff --git a/server/routes/usuario.js b/server/routes/usuario.js index 5efd64b..a17f679 100644 --- a/server/routes/usuario.js +++ b/server/routes/usuario.js @@ -4,10 +4,12 @@ const _ = require('underscore'); const Usuario = require('../models/usuario'); +const { verificaToken, verificaAdminRole } = require('../middlewares/auth'); + const app = express(); -app.get('/usuario', function (req, res) { +app.get('/usuario', verificaToken, (req, res) => { let desde = Number(req.query.desde) || 0; let limite = Number(req.query.limite) || 5; @@ -37,7 +39,7 @@ app.get('/usuario', function (req, res) { }); -app.post('/usuario', function (req, res) { +app.post('/usuario', [verificaToken, verificaAdminRole], (req, res) => { let body = req.body; @@ -68,16 +70,19 @@ app.post('/usuario', function (req, res) { }) -app.put('/usuario/:id', function (req, res) { +app.put('/usuario/:id', [verificaToken, verificaAdminRole], (req, res) => { - let id = req.params.id; + let id = req.params.id; let body = _.pick(req.body, ['nombre', 'email', 'img', 'role', 'estado'] ); // delete body.password; // delete body.google; + //console.log(body); Usuario.findByIdAndUpdate(id, body,{ new: true, runValidators: true }, (err, usuarioDB) => { + console.log(usuarioDB); + if (err) { return res.status(400).json({ ok: false, @@ -92,7 +97,7 @@ app.put('/usuario/:id', function (req, res) { }); }) -app.delete('/usuario/:id', function (req, res) { +app.delete('/usuario/:id', [verificaToken, verificaAdminRole], (req, res) => { let id = req.params.id; diff --git a/server/server.js b/server/server.js index 03e3576..dcc0aff 100644 --- a/server/server.js +++ b/server/server.js @@ -11,8 +11,8 @@ app.use(bodyParser.urlencoded({ extended: false})); // parse application/json app.use(bodyParser.json()); -// Incluyo archivo con las rutas del usuario -app.use( require('./routes/usuario')); +// Incluyo las rutas +app.use(require('./routes/index')); //Conexion a DB // lucas: V7QZDXveXxwkst1l @@ -20,12 +20,13 @@ app.use( require('./routes/usuario')); //console.log( process.env.URLDB ); -mongoose.connect(process.env.URLDB, { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true}, - (err, res) => { +mongoose.connect(process.env.URLDB, + { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, useFindAndModify: false}, + (err, res) => { - if(err) throw new err; - console.log('Base de datos ONLINE!'); + if(err) throw new err; + console.log('Base de datos ONLINE!'); }); -app.listen(process.env.PORT, () => { console.log(`Escuchando el puerto ${process.env.PORT}`); }) +app.listen(process.env.PORT, () => { console.log(`Escuchando el puerto ${ process.env.PORT }`); })