🎯 Ziel dieses Teils
✅ Benutzer dürfen nur ihre eigenen Aufgaben sehen und ändern
✅ Alle Aktionen sind durch Benutzer-ID abgesichert
✅ Es gibt Rückmeldungen bei Fehlversuchen
✅ Im Interface steht, wer gerade eingeloggt ist
Was ist das Problem?
Aktuell nutzt du URLs wie:
/bearbeiten/5
/loeschen/7
Aber:
Ein Benutzer könnte manuell eine andere ID eintippen
(z. B. /loeschen/1
– und damit fremde Daten löschen!)
➡️ Lösung: Immer mit Benutzer-ID absichern!
Schritt 1: Zugriff auf eigene Aufgaben beschränken
Beispiel: /loeschen/<id>
Vorher:
@app.route("/loeschen/<int:id>")
def aufgabe_loeschen(id):
db = get_db()
db.execute("DELETE FROM aufgaben WHERE id = ?", (id,))
db.commit()
return redirect(url_for("startseite"))
Jetzt:
@app.route("/loeschen/<int:id>")
def aufgabe_loeschen(id):
if "user_id" not in session:
return redirect(url_for("login"))
db = get_db()
db.execute(
"DELETE FROM aufgaben WHERE id = ? AND benutzer_id = ?",
(id, session["user_id"])
)
db.commit()
return redirect(url_for("startseite"))
🔐 Nur Aufgaben löschen, die dem eingeloggten Benutzer gehören
Schritt 2: Das gleiche Prinzip bei allen Aktionen
/erledigt/<id>
/zuruecksetzen/<id>
/bearbeiten/<id>
/bearbeiten/<id> [POST]
Immer:
WHERE id = ? AND benutzer_id = ?
Schritt 3: Fehlermeldung bei unerlaubtem Zugriff
Beispiel:
@app.route("/bearbeiten/<int:id>")
def aufgabe_bearbeiten(id):
if "user_id" not in session:
return redirect(url_for("login"))
db = get_db()
aufgabe = db.execute(
"SELECT * FROM aufgaben WHERE id = ? AND benutzer_id = ?",
(id, session["user_id"])
).fetchone()
if aufgabe is None:
return "❌ Zugriff verweigert", 403
return render_template("bearbeiten.html", id=id, text=aufgabe["text"])
Du kannst hier später auch Flash-Meldungen oder eine eigene Fehlerseite einbauen.
Schritt 4: Aktuellen Benutzer im Template anzeigen
In deinen Templates kannst du prüfen, ob jemand eingeloggt ist:
{% if session.name %}
<p>👤 Eingeloggt als: {{ session.name }} | <a href="/logout">Logout</a></p>
{% endif %}
Setze das am besten in den <body>
-Bereich von index.html
.
Schritt 5: Zugang zu geschützten Routen vereinheitlichen
Um dich nicht ständig zu wiederholen, kannst du eine kleine Hilfsfunktion bauen:
def login_erforderlich():
if "user_id" not in session:
return redirect(url_for("login"))
Dann überall am Anfang von geschützten Routen:
@app.route("/hinzufuegen", methods=["POST"])
def aufgabe_hinzufuegen():
r = login_erforderlich()
if r: return r
...
Optional kann man das später auch mit einem eigenen Decorator wie @login_required
eleganter lösen.
Teste deine Sicherheit
- Logge dich als Benutzer A ein
- Erstelle Aufgabe → z. B.
/bearbeiten/3
- Logge dich als Benutzer B ein
- Versuche,
/bearbeiten/3
aufzurufen
→ Zugriff verweigert! ✅
Was du jetzt kannst
Thema | Umsetzung |
---|---|
Zugriff auf eigene Daten | SQL mit benutzer_id = ? |
Session anzeigen | {{ session.name }} im Template |
Zugriff absichern | if "user_id" not in session |
Fehlerbehandlung | Rückgabe 403 , eigene Nachricht |
Bonus-Ideen
- 💬 Flash-Nachrichten (Erfolg / Fehler)
- 🔁 Weiterleitung zurück zur ursprünglichen Seite nach Login
- 🚨 Logbuch: Wer hat was geändert?
Schreibe einen Kommentar