Oturumu Kapatma
Coddy'nin Node.js Journey'sinin Kimlik Doğrulama ve Güvenlik bölümünün bir parçası. Ders 7 / 17.
Çerezi temizlemek yalnızca tarayıcıdan kimliği unutmasını ister. İster başka bir cihazdan ister çalınmış bir çerezden olsun, onu kopyalayan herkes hâlâ çalışan bir anahtara sahiptir. Oturum kapatılırken sunucudaki oturum silinmelidir.
res.clearCookie(name) tarayıcıya bir çerezi silmesini söyler. 204 No Content durumu, işlemin başarılı olduğu ve geri gönderilecek bir şey olmadığı anlamına gelir: res.status(204).end().
İşte kullanıcıyı aynı anda tüm cihazlarda oturumdan çıkaran ilgili bir rota:
app.post('/logout-everywhere', requireUser, async (req, res) => {
await sessions.deleteMany({ userId: new ObjectId(req.user.id) });
res.clearCookie('sid');
res.status(204).end();
});Görev
KolayPOST /logout,sidçerezinin oturumunu siler, çerezi temizler ve 204 yanıtı verir.- Oturum yoksa da 204 yanıtı verir.
Giriş yap, POST /logout gönder, ardından GET /me gönder.
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 });
});
// Oturum çerezinin kullanıcısını bulur veya 401 yanıtı verir.
async function requireUser(req, res, next) {
const { sid } = parseCookies(req.get('cookie'));
const session = sid && (await sessions.findOne({ _id: sid }));
const user = session && (await users.findOne({ _id: session.userId }));
if (!user) {
return res.status(401).json({ error: 'Log in first' });
}
req.user = { id: user._id.toHexString(), username: user.username };
next();
}
app.get('/me', requireUser, (req, res) => {
res.json({ username: req.user.username });
});
// Bu tarayıcının GET /visit isteğini kaç kez yaptığını 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: Her kullanıcı yalnızca kendi notlarını okur ve yazar.
app.get('/notes', requireUser, async (req, res) => {
res.json(await notes.find({ owner: req.user.id }).toArray());
});
app.post('/notes', requireUser, async (req, res) => {
const note = { owner: req.user.id, 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');
});
Kimlik Doğrulama ve Güvenlik bölümündeki tüm dersler
2Oturumlar ve Çerezler
Çerezlerle HatırlamaGiriş Oturumları