domingo, 23 de febrero de 2020

Cómo servir archivos o ficheros desde NodeJS y Express

El uso habitual de Express y NodeJS es la publicación de servicios que respondan con un conjunto de datos, habitualmente en formato JSON.

Pero, ¿cómo podemos responder con un fichero, como un PDF, una imagen o una hoja de cálculo?

La respuesta está en el siguiente código:

const express = require('express');
const path = require('path');
const fs  = require('fs');

const app = express();

app.get('/repository/:file', function (req, res) {
   const filePath = path.join(__dirname, `docs/${req.params.file}`);
   const stat = fs.statSync(filePath);

   res.writeHead(200, {
       'Content-Type': 'application/pdf',
       'Content-Length': stat.size
   });

   var readStream = fs.createReadStream(filePath);
   
   readStream.pipe(res);
});

app.listen(3000, function () {
  console.log('Example app serving files on port 3000!');
});

El servicio atenderá a la siguiente URL:

http://:3000/repository/

La segunda línea, define la ruta de acceso al fichero. En este caso, la ruta será, partiendo de la ruta del código, añadirá la carpeta docs, en la cual se alojan los archivos.

/docs

La tercera línea obtendrá el número de bytes del fichero a enviar.

A continuación, se prepara la cabecera de la respuesta (mediante res.writeHead), indicando que el archivo a enviar será de tipo PDF (atributo Content-Type), junto con el número de bytes que se envía (atributo Content-Length).

Después, se crea un stream de lectura del fichero (mediante createReadStream), al que se le conecta un pipe a la respuesta. Esta operación lee el fichero y envía los datos a la respuesta. Resumiendo, el flujo de lectura del fichero estará conectado al flujo de escritura en la respuesta del servicio.

Enlaces de interés:



miércoles, 14 de agosto de 2019

Encriptación de columnas en PostgreSQL

PostgreSQL es una base de datos relacional ideal para diferentes escenarios, con una larga historia desde 1982 en el corazón de la Universidad de Berkeley hasta nuestros días. Entre sus características más notables destacan su alta concurrencia, la variedad de tipos de datos nativos, tratamiento de datos geométricos, soporte a transacciones distribuidas, drivers para multitud de lenguajes de programación, alta seguridad o su disponibilidad en entornos cloud como Azure o AWS.

Dentro de la materia de Seguridad, encontramos artefactos para implementar la encriptación mediante diferentes opciones (consultar la documentación oficial). Una de estas formas de encriptación la encontramos a nivel de columna, la cual podemos implementar a través de una extensión llamada pgcrypto. Para usar esta extensión, debemos crearla dentro de la base de datos en uso mediante el comando:

CREATE EXTENSION pgcrypto;


Ahora tenemos a nuestra disposición nuevas funciones para incorporar en el lenguaje SQL, a nivel de columna.

La primera función se llama PGP_SYM_ENCRYPT(), y permite encriptar un texto dado, mediante al algoritmo especificado. La siguiente sintaxis encripta mi nombre mediante el algoritmo AES-KEY:

PGP_SYM_ENCRYPT('Rafael','AES_KEY')

La segunda función se llama PGP_SYM_DECRYPT(), y desencripta la columna encriptada mediante el algoritmo especificado:

PGP_SYM_DECRYPT(nombre_columna::bytea, 'AES_KEY')


Ejemplo

Vamos a poner en práctica lo anterior. En primer lugar vamos a crear una tabla de usuarios, en donde almacenaremos los nombres de usuarios y su contraseña, la cual vamos a encriptar para evitar robo de contraseñas:

CREATE TABLE usuarios(nombre VARCHAR(50), password VARCHAR(255));

INSERT INTO usuarios (nombre, password) VALUES ('Rafael', PGP_SYM_ENCRYPT('mypassword','AES_KEY'));

Si se lista la información, veremos que la contraseña está encriptada:

SELECT nombre, password FROM usuarios;

Para ver los datos desencriptados, utilizaremos la siguiente sentencia:

SELECT nombre, pgp_sym_decrypt(password::bytea,'AES_KEY') FROM usuarios;

La siguiente sentencia cambia la contraseña, encriptando la misma:

UPDATE usuarios SET password=(PGP_SYM_ENCRYPT('newpassword', 'AES_KEY'));

Podemos hacer una búsqueda comparando el valor en plano con el valor desencriptado de la columna encriptada. En nuestro ejemplo, cuando hacemos un login, hemos de comparar el nombre y la contraseña. La siguiente sentencia resuelve el problema:

SELECT COUNT(*) AS coincidencias FROM usuarios WHERE nombre = 'Rafael' AND PGP_SYM_DECRYPT(password::bytea, 'AES_KEY') = 'newpassword';


Ver también




domingo, 9 de septiembre de 2018

Contenido pornográfico en la red social Google Plus

Estoy realizando un Máster de Big Data y Business Intelligence aplicado a la empresa y al eCommerce. En el módulo de Community Manager, debo hacer un ejercicio estudiando al Community Manager de una empresa de mi elección, y de cómo hace su trabajo en las diferentes redes sociales.

La empresa de mi elección ha sido Google. Cuando he buscado a Google en su propia red social, Google Plus, me he llevado la sorpresa de que, tras los resultados de páginas y colecciones, en las primeras posiciones, aparecen artículos o publicaciones de contenido pornográfico.


¿Cómo le puede pasar ésto a Google? ¿Se ha producido un fallo en su filtro? ¿Ha fallado su Inteligencia Artificial? ¿Cómo puede permitir esto?