Webbaserad inloggning

(2002-05-12)

Det här med inloggning består av tre steg, skulle man kunna säga. Först ska användaren mata in namn och lösenord (1), sedan ska datorn kolla om det stämmer (2) och slutligen ska den berätta för övriga sidor på webbplatsen att personen gjort en korrekt inloggning (3), så man inte måste mata in uppgifterna på nytt på varje sida, för det skulle man ju snabbt tröttna på.

För steg ett gör vi ett litet forumlär i html:

(login.html)

<form action="verify.php" method="post" name="login">
Användarnamn: <input type="text" name="username"><br>
Lösenord: <input type="password" name="password"><br>
<input type="submit" name="done" value="Logga in">
</form>

Sedan är det dags för steg två, nämligen att kolla om uppgifterna stämmer:

(verify.php)

Om du vill ha flera olika användarnamn och lösenord som man ska kunna logga in med kan du lägga dessa i en associativ array, så här:

$passwords["användarnamn"] = "lösenord";

Exempelvis:

$passwords["alice"] = "gurka";
$passwords["bob"] = "tomat";

If-satsen ovan för att kolla inloggningsuppgifterna blir då så här:

if ($passwords[$_POST["username"]] == $_POST["password"])

* * *

Nu kommer vi till steg tre, och då blir det lite värre, för vi kan ju inte bara använda en variabel för att tala om att personen är inloggad, för användaren kan nämligen själv välja vilka variabler som ska skickas mellan sidor och vad de ska innehålla. Det har man ingen kontroll över som webbplatsinnehavare.

Om du bara gjorde så att efter att Alice hade loggat in sparade värdet "Alice är inloggad" i en cookie (som det heter) så skulle hon kunna ändra det till "Bob är inloggad" utan att du märkte något och vips skulle hon komma åt Bobs saker (om du nu har någon uppdelning). Men vad värre är, om Mallory kommer och vill logga in så skulle hon kunna skicka "Alice är inloggad" till din webbplats och bli inloggad utan att ange något lösenord.

Därför måste vi använda oss av lite kryptering, närmare bestämt en hash-funktion som är inbyggd i php och heter md5.

MD5 är som en svart låda. Du stoppar in något i den och så får du något annat tillbaka, men du vet inte hur det gick till. (Fast om du skulle vilja veta så finns faktiskt formeln beskriven här: http://www.faqs.org/rfcs/rfc1321.html)

När man skickar något till md5 så får man alltid 32 tecken tillbaka oavsett hur många tecken man skickade. Och dessa 32 tecken ska inte på något vis påminna om det du skickar in, för det ska inte gå att gå bakvägen och få reda på vad man skickade in, utan md5 funkar bara åt ett håll. Men du får alltid samma resultat med md5 om du skickar in samma sak, och det är det som är finessen; det är så man kan kontrollera att det stämmer.

När nu Alice loggar in så sätter du återigen värdet "Alice är inloggad", men du kör också "Alice är inloggad" genom md5 och får: 605d4982c9b4849ad73522f7ddc75b98 och sparar även det värdet i en cookie.

När Alice sedan försöker gå in på någon sida skickar hennes dator över cookien "Alice är inloggad" och 605d4982c9b4849ad73522f7ddc75b98 och du kör md5 på "Alice är inloggad" och jämför med de 32 tecken hon skickade med. Stämmer det så vet du att hon inte har ändrat på inloggningen. För om hon nu skulle ändra till "Bob är inloggad" så skulle det bli dc011293eefc34a6c91727f09daa2184 när du kör md5 på det, och då stämmer det inte med de 32 tecken hon fick av dig tidigare.

Fast nu råkar ju Alice vara lite intelligent. Hon har nämligen också tillgång till php och därmed md5-funktionen. Så, hon tar helt enkelt och kör "Bob är inloggad" genom md5 och kan därmed skicka de rätta 32 tecknen till dig så du tror att det verkligen är Bob som är inloggad.

Ja, där har vi ännu ett problem vi måste lösa, och det går att lösa med hjälp av en hemlig kod. Vi antar för exemplets skull att den hemliga koden är "hemlig_kod". Innan vi nu skickar "Alice är inloggad" till md5 så sätter vi ihop det med "hemlig_kod" så vi får: "Alice är inloggadhemlig_kod". När vi skickar det genom md5 får vi: 71d2e5028c2b48d68c33332e51788d10 och dessa 32 tecken skickar vi till Alice tillsammans med "Alice är inloggad", men den hemliga koden får hon absolut inte.

Nu kan inte Alice ändra "Alice är inloggad", för trots att hon har tillgång till md5 så kan hon inte räkna ut de 32 tecknena, för till det behövs den hemliga koden.

Men det finns fortfarande ett problem. Mallory hälsar nämligen på hos Alice en dag och hittar de 32 tecknena från din sida som står för "Alice är inloggad". Med hjälp av dessa kan hon nu logga in som Alice från sin egen dator.

För att lösa det problemet får man tillsammans med den hemliga koden också baka in ett klockslag, så att de 32 tecknen bara gäller exempelvis en timme, sedan måste man logga in på nytt. Då har Mallory ingen nytta av koden eftersom den ändå är värdelös innan hon hunnit komma hem.

Men, i princip så här (vid godkänd inloggning):

$hemligKod = "hemlig";
$tid = time() + 3600;
$hash = md5($_POST["username"] . $tid . $hemligKod);
SetCookie("username", $_POST["username"], time() + 3600, "/", "", 0);
SetCookie("tid", $tid, time() + 3600, "/", "", 0);
SetCookie("hash", $hash, time() + 3600, "/", "", 0);

Sedan, på varje sida som kräver inloggning för att ses gör du så här:

$hemligKod = "hemlig";
if (($tid < time()) || md5($username . $tid . $hemligKod) != $hash)
{
  header("Location: login.html");
  exit;
  // Ej godkänd inloggning.
}
// Här kommer den riktiga sidan.

De här sakerna som jag berättar nu är väldigt viktiga när man jobbar med inloggning, men tyvärr känner inte alla som jobbar med sånt till dem. (Exempelvis har Hotmail missat på en del punkter vilket gör att man kan komma åt andras konton.) Så det är därför jag talar om ganska mycket, så att ni förhoppningsvis åtminstone ska komma ihåg att det är väldigt mycket man måste tänka på för att få det säkert.

Kategorier

Start / Datorer / Programmering /


Fler artiklar