Login-Sitzungen
Teil des Abschnitts Authentifizierung und Sicherheit der Node.js-Journey von Coddy. Lektion 5 von 17.
Die Anmeldung liefert 200 zurück, doch bei der nächsten Anfrage ist vergessen, wer sich angemeldet hat. Eine Sitzung merkt sich das. Bei der Anmeldung erstellt der Server eine ID, die niemand erraten kann, speichert, zu welchem Benutzer sie gehört, und sendet sie als Cookie. Jede spätere Anfrage bringt die ID zurück, und der Server sucht sie nach.
Die ID muss zufällig sein. Ein Cookie mit dem Benutzernamen würde es jedem ermöglichen, Cookie: sid=ada einzugeben und Ada zu sein. randomBytes(24) liefert 192 zufällige Bits. Setze das Cookie auf httpOnly, damit Skripte auf der Seite es nicht lesen können.
const cartId = randomBytes(24).toString('base64url');
await carts.insertOne({ _id: cartId, items: [] });
res.cookie('cart', cartId, { httpOnly: true });
// bei einer späteren Anfrage
const cart = await carts.findOne({ _id: parseCookies(req.get('cookie')).cart });Aufgabe
EinfachPOST /loginspeichert{ _id: sid, userId }insessionsund setzt dassid-Cookie mithttpOnlyundrandomBytes(24).toString('base64url').GET /megibt für diese Sitzung{ username }zurück oder 401{ "error": "Log in first" }.
Registriere dich, melde dich an, sende GET /me und sieh dir dann Daten 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 cookies = parseCookies(req.get('cookie'));
const visits = Number(cookies.visits ?? 0) + 1;
res.cookie('visits', String(visits));
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');
});
Alle Lektionen in Authentifizierung und Sicherheit
4Eigentümer und Sicherheit
Nur deine NotizenAdmin-Rollen2Sitzungen und Cookies
Mit Cookies merkenLogin-Sitzungen