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}`);
});Desafío
FácilGET /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.
- En
server.js, enGET /visit, lee las cookies que envió el navegador, usandoparseCookiescomo se muestra en la lección. El recuento está en la cookie llamadavisits. Llega como texto, por ejemplo,"2". En la primera visita no está presente, lo que cuenta como 0. - Suma 1 al recuento como número, para que
"2"se convierta en3, no en"21". - Establece la cookie
visitscon el nuevo recuento, para que el navegador la envíe de vuelta la próxima vez. - 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');
});
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
2Sesiones y cookies
Recordar con cookiesUna consulta de sesiónSesiones de inicio de sesiónRutas protegidas por inicio de sesiónPractica por tu cuenta: Playground de Express