Menu
CoddyTech

Mit Cookies erinnern

Teil des Abschnitts Authentifizierung und Sicherheit der Node.js-Journey von Coddy. Lektion 8 von 24.

HTTP vergisst dich zwischen Anfragen: Jede trifft einzeln ein, und der Server kann nicht erkennen, dass sie vom selben Browser stammt. Ein Cookie löst dieses Problem. Der Server antwortet mit einem Set-Cookie-Header, und der Browser sendet den Wert bei jeder späteren Anfrage an diese Website in einem Cookie-Header zurück.

res.cookie(name, value) setzt ein Cookie. req.get('cookie') liest den vom Browser gesendeten Cookie-Header als eine Textzeile aus. Express liest den Cookie-Header nicht für dich aus (das würde das Paket cookie-parser übernehmen), deshalb stellt dir cookies.js parseCookies zur Verfügung. Jeder Wert kommt als Text an.

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

Aufgabe

Einfach

GET /visit sollte zählen, wie oft dieser Browser den Endpunkt aufgerufen hat. Der Server speichert den Zählerstand nicht. Der Zählerstand wird in einem Cookie übertragen, und der Browser sendet es bei jeder Anfrage zurück.

  1. Lies in server.js innerhalb von GET /visit die vom Browser gesendeten Cookies aus, indem du wie in der Lektion gezeigt parseCookies verwendest. Der Zählerstand steht im Cookie namens visits. Er kommt als Text an, etwa "2". Beim ersten Besuch fehlt er und zählt daher als 0.
  2. Erhöhe den Zählerstand als Zahl um 1, sodass aus "2" 3 wird und nicht "21".
  3. Setze das Cookie visits auf den neuen Zählerstand, damit der Browser es beim nächsten Mal zurücksendet.
  4. Antworte mit dem neuen Zählerstand als Zahl, nicht als Text: {"visits": 3}.

Probier es aus: Drücke auf „Spielen“. Sende GET /visit: {"visits": 1}. Sende es erneut: {"visits": 2}. Sende es ein drittes Mal: {"visits": 3}. Öffne in dieser Antwort den Tab „Headers“: Set-Cookie gibt visits=3; Path=/ an.

Probier es selbst

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 });
});

// Zählt, wie oft dieser Browser GET /visit aufgerufen hat.
app.get('/visit', (req, res) => {
    const visits = 1;
    res.json({ visits });
});

// Notizen. Vorerst kann jeder sie lesen und schreiben.
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 iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Authentifizierung und Sicherheit

Übe selbstständig: Express-Playground