Menu
CoddyTech

Recordar con cookies

Parte de la sección Autenticación y seguridad del Journey de Node.js de Coddy. Lección 8 de 24.

HTTP se olvida de ti entre solicitudes: cada una llega por separado y el servidor no puede saber que procede del mismo navegador. Una cookie lo soluciona. El servidor responde con un encabezado Set-Cookie y el navegador devuelve el valor en un encabezado Cookie en cada solicitud posterior a ese sitio.

res.cookie(name, value) establece una. req.get('cookie') lee el encabezado Cookie que envió el navegador, como una sola línea de texto. Express no lee el encabezado Cookie por ti (lo haría el paquete cookie-parser), así que cookies.js te proporciona parseCookies. Todos los valores llegan como texto.

app.get('/theme/:name', (req, res) => {
    res.cookie('theme', req.params.name);
    res.send('Saved');
});

app.get('/', (req, res) => {
    const { theme = 'light' } = parseCookies(req.get('cookie'));
    res.send(`Your theme is ${theme}`);
});
challenge icon

Desafío

Fácil

GET /visit debería contar cuántas veces lo ha llamado este navegador. El servidor no guarda el recuento. El recuento viaja en una cookie y el navegador la envía de vuelta en cada solicitud.

  1. En server.js, en GET /visit, lee las cookies que envió el navegador, usando parseCookies como se muestra en la lección. El recuento está en la cookie llamada visits. Llega como texto, por ejemplo, "2". En la primera visita no está presente, lo que cuenta como 0.
  2. Suma 1 al recuento como número, para que "2" se convierta en 3, no en "21".
  3. Establece la cookie visits con el nuevo recuento, para que el navegador la envíe de vuelta la próxima vez.
  4. Responde con el nuevo recuento como número, no como texto: {"visits": 3}.

Pruébalo: Pulsa «Ejecutar». Envía GET /visit: {"visits": 1}. Envíalo de nuevo: {"visits": 2}. Envíalo por tercera vez: {"visits": 3}. Abre la pestaña Headers de esa respuesta: Set-Cookie indica visits=3; Path=/.

Pruébalo tú mismo

import express from 'express';
import { parseCookies } from './cookies.js';
import { notes, users } from './db.js';
import { hashPassword, verifyPassword } from './passwords.js';

const app = express();
app.use(express.json());

app.post('/signup', async (req, res) => {
    const username = String(req.body.username ?? '').trim().toLowerCase();
    const password = String(req.body.password ?? '');
    if (!username || password.length < 8) {
        return res.status(400).json({ error: 'Pick a username and a password of at least 8 characters' });
    }
    if (await users.findOne({ username })) {
        return res.status(409).json({ error: 'That username is taken' });
    }
    await users.insertOne({ username, passwordHash: await hashPassword(password) });
    res.status(201).json({ username });
});

app.post('/login', async (req, res) => {
    const username = String(req.body.username ?? '').trim().toLowerCase();
    const user = await users.findOne({ username });
    if (!user || !(await verifyPassword(String(req.body.password ?? ''), user.passwordHash))) {
        return res.status(401).json({ error: 'Wrong username or password' });
    }
    res.json({ username: user.username });
});

// Cuenta cuántas veces este navegador ha llamado a GET /visit.
app.get('/visit', (req, res) => {
    const visits = 1;
    res.json({ visits });
});

// Notas. Por ahora, cualquiera puede leerlas y escribirlas.
app.get('/notes', async (req, res) => {
    res.json(await notes.find().toArray());
});

app.post('/notes', async (req, res) => {
    const note = { text: String(req.body.text ?? '') };
    await notes.insertOne(note);
    res.status(201).json(note);
});

app.listen(3000, () => {
    console.log('Vault is running on port 3000');
});
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Autenticación y seguridad

Practica por tu cuenta: Playground de Express