🎯 Ziel dieses Teils
✅ Mehr Sicherheit
✅ 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/3aufzurufen
→ 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