Giriş Gerektiren Rotalar
Coddy'nin Node.js Journey'sinin Kimlik Doğrulama ve Güvenlik bölümünün bir parçası. Ders 6 / 17.
Her özel rota, GET /me isteğindeki oturum sorgulamasına ihtiyaç duyar. Her rotaya kopyalanırsa bir gün unutulur ve o rota herkese açık hâle gelir. Bunun yerine, bunu bir ara yazılım olarak bir kez yaz.
Ara yazılım rotadan önce çalışır. Ya yanıt verir ve işlemi durdurur ya da bulduğunu req üzerine ekleyip next() çağrısını yapar. Bunu, gereksinim duyan her rotaya işleyiciden önce aktar:
function requireAdult(req, res, next) {
if (Number(req.query.age) < 18) {
return res.status(403).json({ error: 'Adults only' });
}
req.adult = true;
next();
}
app.get('/wines', requireAdult, (req, res) => res.json(wines));return önemlidir: o olmazsa rota da çalışır.
Görev
KolayrequireUserişlevini yaz: Geçerli bir oturum yoksa 401{ "error": "Log in first" }yanıtını ver; aksi hâldereq.user = { id, username }ata venext()çağır.GET /me,GET /notesvePOST /notesbu işlevi kullanır. Notlarowner: req.user.iddeğerini saklar veGET /notesyalnızca sana ait notları listeler.
Oturum kapalıyken GET /notes isteği gönder, ardından giriş yap ve bir not ekle.
Kendin dene
import express from 'express';
import { randomBytes } from 'node:crypto';
import { parseCookies } from './cookies.js';
import { notes, sessions, 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' });
}
const sid = randomBytes(24).toString('base64url');
await sessions.insertOne({ _id: sid, userId: user._id, createdAt: new Date() });
res.cookie('sid', sid, { httpOnly: true });
res.json({ username: user.username });
});
app.get('/me', async (req, res) => {
const { sid } = parseCookies(req.get('cookie'));
const session = sid && (await sessions.findOne({ _id: sid }));
if (!session) {
return res.status(401).json({ error: 'Log in first' });
}
const user = await users.findOne({ _id: session.userId });
res.json({ username: user.username });
});
// Bu tarayıcının GET /visit isteğini kaç kez gönderdiğini sayar.
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 });
});
// Notlar. Şimdilik herkes bunları okuyabilir ve yazabilir.
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');
});
Bu ders kısa bir quiz içerir. Soruları yanıtlamak ve ilerlemeni kaydetmek için derse başla.
Kimlik Doğrulama ve Güvenlik bölümündeki tüm dersler
2Oturumlar ve Çerezler
Çerezlerle HatırlamaGiriş Oturumları