Avatar billede doncarnage Nybegynder
25. juli 2009 - 21:49 Der er 22 kommentarer og
1 løsning

Lidt hjælp til en function i mit rangsystem

Godaften kære eksperter,

Jeg vil endnu en gang benytte chancen til at spørge jer til råds, da jeg sidder lidt fast med mit rangsystem :)

Jeg har 2 funktioner i mit simple rangsystem indtil videre. Den ene funktion tjekker op på om man er logget ind og om password stemmer overens med brugerens oplysninger. Denne ses her:

---------------------------------------------------------------------------------------------------------------------
function CheckLogin()
{
  if (!isset($_SESSION["SESS_MEMBER_ID"]) || !isset($_SESSION["SESS_PASSWORD"]))
    return false;
  $string = "SELECT password FROM members_regi WHERE id=".$_SESSION["SESS_MEMBER_ID"];
  $query = mysql_query($string);
  return ($query && $_SESSION["SESS_PASSWORD"] == mysql_result($query, 0));
}
---------------------------------------------------------------------------------------------------------------------

Den anden funktion gør stort set det samme, men her bliver der dog yderligere spurgt ind til om man er administrator eller bruger (bruger = rank 0, administrator rank = 1). Denne funktion ses her:

---------------------------------------------------------------------------------------------------------------------
function CheckLoginRank()
{
  $db_rank = mysql_query("SELECT * FROM members_regi WHERE id='".$_SESSION['SESS_MEMBER_ID']."'") or die(mysql_error());
  $rettigheder = mysql_fetch_array($db_rank);
  if ($rettigheder['rank'] == '0' || !isset($_SESSION["SESS_MEMBER_ID"]) || !isset($_SESSION["SESS_PASSWORD"]))
    return false;
  $string = "SELECT password FROM members_regi WHERE id=".$_SESSION["SESS_MEMBER_ID"];
  $query = mysql_query($string);
  return ($query && $_SESSION["SESS_PASSWORD"] == mysql_result($query, 0));
}
---------------------------------------------------------------------------------------------------------------------

Mit spørgsmål lyder så på hvordan jeg laver en ny, lignende funktion som gør sådan at funktionen er "sand" hvis:
$_SESSION["SESS_MEMBER_ID"] == userid (som er en række i tabellen forum_topics)

Det jeg skal bruge det til er et redigeringssystem, hvor brugerne skal kunne redigere deres egne tråde, hvis deres session id stemmer overens med det indtastede userid i databasen. Men hvordan gør jeg det?
Avatar billede repox Seniormester
25. juli 2009 - 22:02 #1
Er det nogle funktioner du kører for hvert load? Eller for hver gang du skal bruge en brugers rang?

Det ville være væsentligt bedre at lave en samlet funktion der køres en enkelt gang når brugeren er logget ind hvor du så har oplysningerne, som du skal bruge gemt i en session.

F.eks:
function loginUser($username, $password)
{
    $username = mysql_real_escape_string($username);
    $password = md5($password);
   
    //Check om brugeren kan logge ind
    $sql = "SELECT id, rank FROM members_regi WHERE username = '".$username.'" AND password='".$password."' LIMIT 1";
    $result = mysql_query($sql);
   
    if(mysql_num_rows($result) == 0)
        return false;
       
    $userId = mysql_result($result, 0, "id");
    $rank = mysql_result($result, 0, "rank");
   
    $_SESSION["SESS_MEMBER_ID"] = $userId;
    $_SESSION["SESS_MEMBER_RANK"] = $rank;
   
    return true;
}

Så tjekker du bare om brugeren er logget på ved at kontrollere sessionen SESS_MEMBER_ID, for den kan jo kun være sat hvis du har logget ind, ikke?

Anyways, du vil gerne have folk skal kunne se om de må rette et indlæg i en tråd?
Avatar billede doncarnage Nybegynder
25. juli 2009 - 22:10 #2
Altså, jeg inkluder funktionerne fra en fil og de steder jeg skal bruge dem loader jeg dem så hver gang jeg skal bruge en brugers rank:

        if (!CheckLogin()){

        }
       
        else{

        }

Er det en dum måde at gøre det på da? Har nemlig gjort det pænt mange steder på siden, så det er et større arbejde hvis det skal til at omstruktureres :/

Men jeps.. Der skal være en knap synlig for de brugere, hvis session id svarer til userid i tabellen forum_topics. Altså hvis de selv har skrevet tråden skal de kunne redigere ;)
Avatar billede doncarnage Nybegynder
25. juli 2009 - 22:18 #3
Jeg kan i princippet bare gøre sådan her på siden:

if ($row['userid'] == $_SESSION['SESS_MEMBER_ID']){
echo "userid passer";
}
else{
echo "userid passer ikke";
}

Men tænkte bare at det måske ville være smartere at samle det i en function :S
Avatar billede doncarnage Nybegynder
25. juli 2009 - 22:32 #4
Og ovenstående er vidst heller ikke helt sikkert ;)
Avatar billede repox Seniormester
25. juli 2009 - 22:33 #5
At spørge databasen for hvert sideload giver ikke meget mening, medmindre årsagen er at brugerens status, oplsyninger eller lignende kan ændre sig forholdsvis ofte.

Optimer dit resourceforbug. Simpelt kan godt være smart.

Men tilbage til spørgsmålet.

Når du henter dine trådindlæg ud trækker du også forfatterens ID med ud. Det behøver du ikke lave en funktion til, du skal i princippet bare sammenligne forfatter id'et med session id'et for hvert indlæg.

Det eneste tidspunkt det bliver relevant at kontrollere om brugeren reelt har tilhør til indlægget er når du kommer til redigeringssiden af indlægget. Du behøver ikke nogle 'smarte' funktioner til formålet.
Avatar billede repox Seniormester
25. juli 2009 - 22:38 #6
udover at dit forslag nok ikke ville virke, så har du da idéen. Jeg ville gøre noget ala:

<?php

    if(!isset($_SESSION["userId"]))
    {
        header("Location: login.php");
        exit;
    }

    //fortsæt med at vise sidens indhold.

?>
Avatar billede doncarnage Nybegynder
25. juli 2009 - 22:47 #7
Jeg tror bare selv det bliver for besværligt at få en funktion ind som du snakker om i mit loginscript, da jeg bl.a. også benytter mig af cookies.. Så bliver funktionen jo ikke kørt næste gang de besøger siden med cookies medmindre jeg kører funktionen igen, men så er vi jo lige vidt :S


if ($row['userid'] == $_SESSION['SESS_MEMBER_ID']){
echo "userid passer";
}
else{
echo "userid passer ikke";
}

Ovenstående virker nu fint nok (når man self. forbinder til databasen først).. Jeg har bare hørt at det skulle være nemt for en hacker at genere et nyt session id, og derved virker det ikke særlig sikkert i mine øjne at gøre det sådan der :/
Avatar billede repox Seniormester
25. juli 2009 - 23:00 #8
Tror desvære du har misforstået mange ting omkring cookies og sessions.

Du er selv ansvarlig for sikkerheden omkring brugen af disse.

En 'hacker' kan generere et nyt session id ligeså nemt som os andre. Når jeg lukker min browser (eller sletter mine cookies fra dit domæne) så har jeg et nyt session id lige så snart jeg åbner din side igen. Men at jeg har en ny session betyder også at min session er tom. Så hvordan du kan udlede, at det ikke er sikkert at gøre sådan, ud fra noget du har hørt som egentlig ikke handler om brugen af dem, forstår jeg ikke.

Det at du benytter cookies har heller ikke noget at sige. Din kode skal i princippet blot kontrollere om du er logget på. Er du ikke det, kontrollerer du om brugeren har den cookie du omtaler. Hvis brugeren har det, forsøger du så at logge ind for brugeren gennem cookiens data og så sætter du de sessions der fortæller din kode at du er logget på.

Det er uhyre simpelt. Det er overkill at have flere funktioner til at kontrollere så simple ting for hvert pageload.
Avatar billede doncarnage Nybegynder
25. juli 2009 - 23:13 #9
Yearh okay, jeg tror det er noget han har bildt mig ind så :/

Men kan du tyde ud fra nedenstånde login-script hvordan jeg så får lavet en funktion som vi snakker om til at tjekke om man er admin eller ej (rank 0, rank 1) og hvordan jeg efterfølgende følger op på det inde på siden så?

<?php
    session_start();
   
    // Forbinder til databasen
    require_once('sql.php');
   
    // Forebyggelse af SQL injections
    function clean($str) {
        $str = @trim($str);
        if(get_magic_quotes_gpc()) {
            $str = stripslashes($str);
        }
        return mysql_real_escape_string($str);
    }
   
    // POST values hentes fra mine forms
    $username = clean($_POST['myusername']);
    $password = clean($_POST['mypassword']);
   
    // Password bliver hashet med salt
    $salt = 'mit salt her :D';
    $passwordhashed = md5($password.$salt);
   

    // Sql query laves
    $qry="SELECT * FROM members_regi WHERE username='$username' and password='$passwordhashed'" or die(mysql_error());
    $result=mysql_query($qry);
   
    // Checker om query var en succes eller ej
    if($result) {
        if(mysql_num_rows($result) == 1) {
       
            // Login
            session_regenerate_id();
            $member = mysql_fetch_assoc($result);
            $_SESSION['SESS_MEMBER_ID'] = $member['id'];
            $_SESSION['SESS_USERNAME'] = $member['username'];
            $_SESSION['SESS_PASSWORD'] = $member['password'];
            $id_db = $member['id'];
            session_write_close();
           
            ///////////////////////////////// COOKIE SCRIPT ////////////////////////////////
            if($_POST['rememberMe']==1 ){
            $usernamecookie = $member['username'];
            $userpwcookie = $member['password'];
            $random = hash(sha256,(uniqid(rand(), true)) . (uniqid(rand(), true)));
            $expire = time() + 60*60*24*30; // Nuværende tid + 30 dage
            $name  = "login"; // Cookiens navn
            $value  = "$usernamecookie<br/>$userpwcookie<br/>$random<br/>$expire"; // Værdier i cookien
            $query = "INSERT INTO `members_cookies` (`id`,`user`, `pw`, `random`,`expire`,`uid`) VALUES (NULL, '$usernamecookie', '$userpwcookie', '$random', '$expire', '$id_db')";
            mysql_query($query);
            $path  = "/"; // Cookien fungerer i alle undermapper
            setcookie($name, $value, $expire, $path);
            }
           
            header("location:".$_SERVER['HTTP_REFERER']);
            exit();
        }else {
            // Login mislykkedes
            header("Location:loginerror.php");
            exit();
        }
    }else {
        header("location:".$_SERVER['HTTP_REFERER']);
        exit();
    }
?>
Avatar billede repox Seniormester
25. juli 2009 - 23:33 #10
Det er godt nok noget grim kode, for så noget så simpelt.
Kører du på en server med PHP4? Koden virker noget forældet...

Anyways, grundlæggende ville jeg gøre således:
http://php.pastebin.com/m25916e5d

Og som jeg skriver i dit kodeeksempel, så er din cookie-del noget gris; det kan lavet smartere og mere generelt.

På den måde har du nu to sessions som du bruger i hele scriptet:
$_SESSION["SESS_MEMBER_ID"] som indeholder bruger id'et
$_SESSION["SESS_MEMBER_RANK"] som indeholder brugeren rang.

Så ville du fremover lave din kontrol som tidligere nævnt.

<?php
    if(!isset($_SESSION["SESS_MEMBER_ID"]))
    {
        header("Location: loginerror.php");
        exit;
    }
?>

Og når du skal kontrollere på rangen:
<?php

    if($_SESSION["SESS_MEMBER_RANK"] == 1)
        echo "admin link, funktion eller hvad det nu kan blive til";

?>
Avatar billede doncarnage Nybegynder
26. juli 2009 - 02:03 #11
Og hvordan vil du så tjekke op på det med edit? Det er vel noget i den dur som jeg selv var inde på ikke?
..............................
if ($row['userid'] == $_SESSION['SESS_MEMBER_ID']){
..............................


Og hvad så med mit cookie script - det skal vel også laves om? Det ser sådan her ud:

http://php.pastebin.com/m10a5ac79

Så vidt jeg selv kan se er det $_SESSION['SESS_MEMBER_RANK'] der skal sættes der, men er ikke sikker på om der skal laves mere.. Blev helt forvirret af at sidde og rette +30 sider igennem S:


Er det mange resourcer man sparer ved at gøre det på denne måde? Synes det virker meget besværligt, men hvis det er det værd og man kan mærke det er det selvfølgelig besværet værd ;)
Avatar billede repox Seniormester
26. juli 2009 - 05:52 #12
Nu kender jeg ikke lige til din udlæsning af dine tråde, men ja, du kontrollerer naturligvis det userid der har oprettet indlægget op mod den session du har dit brugerid i.

Og så dit cookie script...
Jeg er desværre ikke så diplomatisk som jeg burde være, men det er godt nok noget supergrim kode du har fået lavet dig der :/

Der vil ikke være nogen mening i at rette dit cookiescript til, hvis metoden du registrerer din cookie på ikke ændres.

Med hensyn til dit spørgsmål omkring forbrug af resourcer, så skal du flytte dit fokus væk fra hvad du sparer, men mere på hvad du forbruger.

Som jeg har forstået dig, fra det oprindelige setup, så foregik et pageload med noget ala:
Hvis jeg havde en autologin cookie: 2 SQL kald.
CheckLogin(): 1 SQL kald
CheckLoginRank(): Lad os bare sige et gennemsnit på 3 SQL kald pr side?
Og så ville du have en funktion der kunne kontrollere om brugeren måtte redigere et indlæg i en tråd, så hvis vi bare siger 10 indlæg pr tråd i gennemsnit: 10 SQL kald.
Så på en enkelt side havde du pludseligt 16 SQL kald, udover de SQL kald der henter noget af indholdet. Og det er hver gang en side hentes og vises.

Selvom jeg måske har skudt højt, så forstår du sikkert idéen bag min opridsning.
Dit forbrug bliver jo stort, og på et tidspunkt kan det blive kritisk. Og selvom det virker supersmart at pakke sådan noget ind i funktioner, så er det faktisk ikke vildt genialt når du skal spørge efter noget du egentlig godt ved (eller burde vide fra da brugeren loggede ind).
Avatar billede doncarnage Nybegynder
26. juli 2009 - 14:08 #13
Det er jeg ked af at høre :/ Det er første gang jeg arbejder med cookies og det tog også sin tid at få det til at virke (har fulgt denne guide: http://guides.ricehigh.dk/?p=7)

Men hvorfor er der ikke nogen mening i at rette til i cookiescriptet? Hvis jeg tilføjer dette virker det:

$qry="SELECT * FROM members_regi WHERE username='".$username."' and password='".$password."' LIMIT 1";;
$result=mysql_query($qry);
$member = mysql_fetch_assoc($result);
$_SESSION['SESS_MEMBER_RANK'] = $member['rank'];

Men det er måske ligeså ressource krævende som før så?

Kan sagtens følge dig i at det hurtigt bliver tungt og kritisk i takt med at databasen bliver større på den måde... Vil derfor også rigtig gerne have løst problemet, men det er bare lige med hvordan :S
Avatar billede repox Seniormester
26. juli 2009 - 15:30 #14
Hmm, ja. Det er selvfølgelig ikke nemt og vi har allesammen hver vores stil når vi scripter.

Din login funktionalitet kan gøres meget mere generisk, hvilket vil skabe en bedre ramme for dine grundlæggende funktionaliter i forbindelse med brugeradministreringen.

Artiklen du har fundet lugter lidt af at det er et praktisk eksempel udvikleren selv benytter. En slags 'det virker for mig' artikel.

Anyhow, en hurtig gennemgang af artiklen fortæller mig at løsningen er en slags 'udvidelse' af det du har. For mig kan jeg ikke se nødvendigheden af at udvide for at få oplysninger du allerede har.

Se f.eks. det her:
http://php.pastebin.com/mbefffe3

Det er godt nok to scripts i et (lidt doven er man vel) men det skal illustrere hvor simpelt du kan gøre tingene, samtidig med at du gør det sikkert. Resource forbruget er minimalt og koden er nem at vedligholde.
Avatar billede doncarnage Nybegynder
27. juli 2009 - 02:12 #15
Yearh okay :/ Jeg vil prøve at kigge lidt på det når jeg får godt med tid til overs.. Tager nemlig lang tid at få rettet hele siden igennem, så det skal jeg lige ha afsat tid til..
Avatar billede doncarnage Nybegynder
28. juli 2009 - 23:58 #16
Så fik jeg lige fri et par dage, så nu har jeg massere af tid igen ;)

Hvis jeg samler min login del i én fil og bygger det op på den måde som du beskriver i http://php.pastebin.com/mbefffe3 - og så på selve siden spørger på om man er logget ind eller ej/admin eller ej vha. det du foreslår i kommentar #10.. Så er det et "pænt" script jeg har igen eller hvordan?

Hvis jeg gør det på den måde skal jeg heller ikke bruge min cookie tabel i databasen til noget kan jeg se, men det er jeg egentlig også ganske godt tilfreds med, da der er visse ulemper ved det.. Så længe cookie delen bare er sikker ;) Det er desuden også dejligt at du har samlet cookie og login delen i én fil fremfor at jeg har det delt op i to filer..

Jeg synes i midlertidig bare ikke helt det virker når jeg prøver det af.. Eller dvs. hvis jeg logger ind, virker det fint nok.. Men hvis jeg prøver at logge ind med cookie, lukker siden og besøger den igen - så er jeg ikke stadig logget ind :/ Du skulle vel ikke vide hvordan det kan være?

http://php.pastebin.com/m47798d9b

Det eneste jeg sådan set har ændret ud fra dit forslag er navnet på cookien fra "autologin" til "login", og så har jeg ændret på saltet, så det virker ordenligt.. Derudover har jeg bibeholdt min clean funktion, men ved ikke om det overhovedet er nødvendigt..
Avatar billede doncarnage Nybegynder
29. juli 2009 - 01:27 #17
Bah.. det er vidst mig, der sidder og tåger big time.. Selvfølgelig skal jeg stadig bruge min anden config fil til at følge op på cookiens indhold, så sessions kan blive sat når man vender tilbage til sitet ;)

Jeg prøver lige at kigge videre på det..
Avatar billede doncarnage Nybegynder
29. juli 2009 - 01:49 #18
Har fået lavet det nu og det ser ud til at virke som det skal ;) Det store spørgsmål er så bare om koden ser okay ud nu ?

Min login del ser ud som her:
http://php.pastebin.com/m781bef0a

Og min cookie del ser ud som her:
http://php.pastebin.com/m129feb4
Avatar billede repox Seniormester
30. juli 2009 - 01:58 #19
Jeg kunne ikke lige forestille mig at det virker efter hensigten?
Alt hvad du skal bruge ligger heri:
http://php.pastebin.com/m781bef0a
Men alt efter linie 34 vil aldrig eksekveres.

Ligeledes vil http://php.pastebin.com/m129feb4 heller ikke have den ønskede effekt; den er jo taget ud af loginkontrollen, som startede på line 34 i den forrige fil?
Avatar billede doncarnage Nybegynder
30. juli 2009 - 04:16 #20
Hov, godt du opdagede det.. Jeg kan se at jeg har glemt at fjerne det efter linie 34 som du nævnte i den her fil http://php.pastebin.com/m781bef0a

Men det virker nu stadig fuldt ud som det skal efter hensigten :)

Når jeg trykker på "login"-knappen bliver http://php.pastebin.com/m781bef0a kørt igennem (har så lige fjernet det fra linie 34 og ned nu)...

Men hvis jeg så kommer tilbage til siden hvor jeg har gemt login i en cookie bliver filen ikke automatisk kørt, da den kun køres når man trykker på login knappen.. Derfor har jeg gemt http://php.pastebin.com/m129feb4 i en seperat fil som så loades på alle siderne ;)

Er det helt forkert gjort da ? Hvis jeg forstår dig ret har du blot samlet det hele i én fil som så bliver loadet på sitet fra start - også når man ikke har trykket på "login"-knappen..
Avatar billede repox Seniormester
30. juli 2009 - 09:12 #21
Mja, 'helt forkert' er måske ikke helt rigtigt; det at jeg har smidt tingene i en og samme fil i dovenskab var måske heller ikke det smarteste.

Men altså, selve din loginfil bør se sådan ud:
http://php.pastebin.com/m30a8855c

Og den stump kode der kontrollerer om folk er logget ind eller ej, bør se sådan ud:
http://php.pastebin.com/mb2ed2cb

Det er den samme kode som du har præsentæret, bare delt rigtigt op, så kan du jo sammenligne og spørge hvis der er noget.
Avatar billede doncarnage Nybegynder
30. juli 2009 - 12:10 #22
Jeps okay, det er også sådan mine to filer mere eller mindre ser ud nu ;)

Fantastisk..! Du må lige smide et svar, så du kan få dine velfortjente points og så siger jeg tussind tak :D
Avatar billede doncarnage Nybegynder
20. oktober 2009 - 12:50 #23
lukker og slukker
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester