Wat je server laat zien: een vergeten endpoint
In les 2 zag je dat /docs elk endpoint noemt. Ook
GET /sessies, dat je in Onthouden op de server: sessies
maakte om zelf in je sessies te kijken. Daar stond bij: haal het daarna weg.
Wie dat vergat, heeft een endpoint dat niemand anders mag gebruiken, op een
lijst die iedereen kan lezen.
Twee bezoekers
Start je server uit les 1, als hij nog niet draait. Maak een script twee.py met twee bezoekers die
elk een bericht plaatsen. Een Client onthoudt zijn cookie, zoals in
Een bezoeker die onthoudt:
import httpx
sara = httpx.Client(base_url="http://127.0.0.1:8000")
alex = httpx.Client(base_url="http://127.0.0.1:8000")
sara.post("/bericht", data={"naam": "Sara", "bericht": "Hoi allemaal"})
alex.post("/bericht", data={"naam": "Alex", "bericht": "Leuk gastenboek"})
print(sara.get("/ik").json())
print(alex.get("/ik").json())
Uitvoer:
{'naam': 'Sara'}
{'naam': 'Alex'}
Elke bezoeker heeft zijn eigen sessie-id in een cookie, en /ik herkent hem
daaraan.
Wat /sessies weggeeft
Nu ben je een derde bezoeker, zonder cookie, die alleen de handleiding heeft
gelezen. Maak sessies.py:
import httpx
adres = "http://127.0.0.1:8000"
antwoord = httpx.get(adres + "/sessies")
for sessie_id, sessie in antwoord.json().items():
ik = httpx.get(adres + "/ik", cookies={"sessie_id": sessie_id})
print(sessie_id, ik.json())
- Regel 5:
Het vergeten endpoint. Het geeft elke sessie terug, met het sessie-id als sleutel.
- Regel 7:
Met
cookiesstuur je zelf een cookie mee. Het script stuurt het sessie-id van een ander, alsof het zijn eigen cookie is.
Heb je opdracht 2 van les 2 gedaan, dan staat jouw eigen sessie
er ook bij, bovenaan: Execute op /docs maakte er een, met de naam die je
daar invulde.
Een sessie-id is zo lang en willekeurig dat niemand het kan raden. Dat helpt niets meer als je server ze zelf op een rij zet.
In dit kleine gastenboek kan een sessie-id weinig kwaad: /ik zegt alleen een
naam. In je eigen gastenboek is een sessie-id een inlog. Wie het sessie-id van
Sara heeft, is voor je server ingelogd als Sara, zonder haar wachtwoord te
kennen. In de reeks Wie mag wat, die later
komt, mag alleen de schrijver zijn bericht verwijderen, en dat controleert de
server met precies dit sessie-id. Met /sessies erbij kan iedereen elk bericht
verwijderen.
Dit is de zwakheid
Je maakte /sessies voor jezelf, om te testen. De server weet dat niet: hij
beantwoordt elk verzoek, van wie dan ook, en /docs zet het endpoint netjes op
de lijst. Een endpoint dat alleen voor jou is, bestaat niet. In
les 4 zet je de lijst uit en haal je het endpoint weg.
Er gaat iets mis
sessies.py print niets.
Oorzaak: de server heeft geen sessies in zijn sessies.db. Er plaatste nog
niemand een bericht, of je startte de server na twee.py opnieuw vanuit een
andere map. De server opent sessies.db in de map waarin je hem start, en maakt
daar stil een nieuwe, lege aan als hij er niet is. De map van twee.py en
sessies.py maakt niet uit: die praten via HTTP met de server.
Oplossing: start de server in de map veiligheid-zichtbaar, waar main.py
staat. Draai daarna eerst twee.py en dan sessies.py.
Opdrachten
Opdracht 1: Predict - Een verzonnen sessie-id
Je stuurt GET /ik met de cookie sessie_id op abc.
Vraag: wat antwoordt de server?
Tip
Kijk in wie_ben_ik wat sessies.get doet als het sessie-id niet bestaat.
Antwoord
{'naam': 'onbekend'}. Een verzonnen sessie-id staat niet in sessies.db, dus
get geeft de lege dictionary. Raden lukt niet; daarvoor zijn er te veel
mogelijkheden. Alleen een sessie-id dat de server zelf uitdeelt, werkt.
Opdracht 2: Investigate - Welke is erger?
GET /berichten en GET /sessies geven allebei de inhoud van een database
terug, aan iedereen. Waarom is de tweede een gat en de eerste niet?
Antwoord
De berichten zijn bedoeld om te lezen: daarvoor is een gastenboek. Een sessie-id is een sleutel. Wie het heeft, is voor de server die bezoeker. Een lijst met sessie-id's is dus een sleutelbos van al je bezoekers.
Door naar les 4: de handleiding uitzetten.