Dette burde da vel virke, eller mangler jeg noget ?
Testede lige om cookies var blevet sat korret ved log ind ved at udskrive den nysatte cookie på forsiden (index.php) sådan her: $bah = $_COOKIE["loggedin"]; print $bah;
hvilket gav fejlen: Notice: Undefined index: loggedin in C:\blabla\index.php on line 21
Teknologi, AI og forretning er i centrum på Computerworlds Cloud og AI Festival i København d. 18. og 19. september. Se hele programmet for den store konference om strategisk brug af Cloud og AI på: www.cloud-festival.dk
du skriver time() - 3600 det ville sige at du minuser den aktuele tid med 3600 og derved er den jo allerede gammel da den blev oprettet. derfor skal du ændre - med +
Du har forhåbentlig noget mere kode. En cookie er en tekstfil, som ligger på brugerens maskine. Du må endelig ikke stole på, hvad der står i sådan en 'håndskrevet, fedtet lap papir' *o)
Det Ole siger, er at når du så sikkert får det til at virke, så har du verdens mest usikre system. Enhver hacker vil kunne sætte sine egne cookies, med true, og et vilkårligt user_id, og dermed kunne logge ind som hvemsomhelst.
Prøv at få det til at virke, så du kan lære noget om PHP osv, og smid det så væk.
@rix17172 tak, det var problemet. Havde bare læst et sted at hvis man satte den i minus ville den cookie være der indtil man selv valgte at slette den... nu har jeg så bare sat den til et år frem.
@erikjacobsen og olebole: Kan godt se hvad i mener.. :/ hvordan skal jeg så gøre det mere sikkert? er det noget med også at sætte COOKIES for brugernavn og password og tjekke om de passer sammen før man får lov at komme igennem igen eller? hackeren kan jo sagtens sætte sin egen cookie med "true" som du siger, men hvis han også skal sætte en cookie med et korrekt pass er hjælper det vel på sikkerheden. Hvad med sessions, er det det samme med dem?
Jeg tror ikke brugere vil sætte pris på at deres password gemmes, omend måske midlertidigt, på deres maskine. De vil heller ikke synes om at det sendes i klartekst over nettet - derfor selvfølgelig https://....
Men sessions er i hvert fald bedre. Man sætter en cookie, med en rimelig tilfældig lang streng af tegn, som andre ikke så nemt gætter. Den kan stadig lyttes (session-hijacking) - derfor https://..... I en sessions-variabel skriver du så user_id.
Det er i hvert fald sikrere end det du har. Generelt kan man ikke rådgive om sikkerhed, for de valg man foretager sig afhænger af mange ting. Der er forskel på sikkerhed for billederne af sidste druktur til Bulgarien, og så for at holde styr på nationalbankens guldbeholdning.
Det er også kun når man selv vælger at passwordet skal gemmes at der sættes cookies jo. Og de bliver fjernet igen når man vælger at logge ud. Hvis man bare lukker browseren er man stadig logget ind når man besøger siden igen. Hvis man ikke vælger dette, bliver der kun benyttet sessions. Jeg må så lige finde ud af hvordan man undgår session hijacking... Jeg vil selvfølgelig have mit system til at være så sikkert som muligt, men det behøver ikke være helt vanvittigt sikkert da man ikke får så meget ud af at hacke sig ind.
Men jeg siger tak for svarene allesammen! dem der vil have points smider bare svar
Det, du tilbyder brugeren, er, at hun og alle andre brugere problemfrit kan bruge siden uden login. Man skal bare sige 'ja', når man bliver spurgt, om man er inviteret
Du skal ikke være bange for, at det 'ikke er vanvittigt sikkert'. Ordet 'sikkerhed' giver absolut ingen mening i forbindelse med den løsning. Den er ligeså god som vidt åbne døre - uden login =)
- og husk i øvrigt, at det er lovpligtigt, at informere om hver cookie, der bliver sat på dit site (også af Google AdWords og andre) - om hvem, der sætter den, og hvad den skal bruges til.
Brugeren skal have mulighed for at afslå - og hvis brugeren indvilger, skal hun senere have mulighed for at trække samtykket tilbage og få slettet kagen, hvis hun ønsker det.
Hmm tror ikke jeg er helt med på hvad du mener med at man kan bruge siden uden login. Man kan ikke bruge den uden at være logge ind. Jeg har jo også kun postet en meget lille del af koden herinde så du har måske fået et andet billede af det hele? Jeg har begrænset alt indhold på min side (undtagen login siden selvf.) så man kun får lov til at se det hvis man er logget ind.
... eller snakker vi bare fuldstændig forbi hinanden lige nu? :)
Da kun du kender koden, kan kun du afgøre, om vi taler forbi hinanden =)
Hvis cookie'en er det eneste, du genkender ham på, logger du ikke en kendt bruger ind ... så byder du bare en eller anden komplet tilfældig velkommen.
Alle kan komme med en cookie med de nødvendige data. Det kommer bl.a. an på, hvad $_COOKIE["user_id"] indeholder - hvordan den opstår - og hvad du gør med den, efter du har læst den. Det kan jeg (måske) ikke se her =)
okay vi taler forbi hinanden :) cookien er ikke det eneste der genkender brugeren.. der bliver uanset hvad sat sessions hvis det indtastede brugernavn og pass passer sammen. hvis derudover afkrydser "remember me" feltet vil der blive sat cookie som husker brugeren indtil man vælger at logge ud..
Nå, men jeg har fået svar på mine spørgsmål så kan godt lukke tråden nu. Tak for hjælpen. Du samler ikke på points vel ole?
Hvis der er nogen der vil have points må i lige smide et svar
Ja, jeg er helt med på den del. Problemet opstår, når brugeren vender tilbage dagen efter, og du så 'logger ham ind'. Hvis du dér stoler på cookie'en og blindt regner med, at den er sat af dit site i går, står dit system pivåbent.
Du er som minimum nødt til at lave en session i din DB. Når brugeren logger ind (med brugernavn og password), gemmer du en unikt genereret hash i et felt i databasen - knyttet til brugerens ID i brugertabellen. Samtidig gemmer du hash'en i en cookie.
Når brugeren vender tilbage dagen efter - og ikke længere har en aktiv session - læser du kagen og slår hash'en op i databasen. Findes den pågældende hash, lader du den tilknyttede bruger slippe igennem og sætter en session på ham.
NB: Det er vigtigt, at du genererer en ny hash, hvergang brugeren logges ind - hvad enten det sker med bruger/pass eller med cookie
Lige på dette ene punkt er der, som Erik skrev, f.eks. HTTPS - men fænomenet 'sikkerhed' er en kombination af en masse ting. Fænomenet 'usikkerhed' er udeladelse eller dårlig implementering af bare én eneste af disse ting =)
Når en bruger bare kikker sider eller logger sig ind - men uden endnu at være det - så henter han data fra databasen for at få sammenstykket siderne.
Har du nogensinde tænkt over, hvad den MySQL-bruger, du i den situation forbinder til databasen med, har af tilladelser? Kan den bruger lave andet end SELECT - og hvad betyder det, hvis han er klogere end du og trods alle gode forhindringer lykkes med SQL-injection?
Brug af prepared statements og sikker fejlhåndtering er et par andre af de mange ting, du kan bruge for at sikre dig bedre. Al sikkerhed er dog afhængig af, at alle led i kæden er stærke =)
// Create a prepared statement if($stmt->prepare("SELECT `name`, `bio` FROM `table` WHERE `age` = ?")) {
// Bind your variable to replace the ? $stmt->bind_param('i', $age);
// Set your variable $age = 32;
// Execute query $stmt->execute();
// Bind your result columns to variables $stmt->bind_result($name, $bio);
// Fetch the result of the query while($stmt->fetch()) { echo $name . ' - ' . $bio; // John Doe - Unknown... }
// Close statement object $stmt->close(); }
det giver fin nok mening hvordan det virker og hænger sammen, men synes altid der bliver brugt variablen "$stmt", i hvert fald alle de eksempler jeg har set (skal denne bruges?). Hvordan skelner man mellem forskellige kald til forskellige tabeller? Hvis man nu f.eks. et sted ville lave kald til tabel1 og derefter et kald til tabel2. Og hvordan kan man kalde sådan et statement fra en fil for sig selv (bare for at holde det lidt adskilt)?
Du må i princippet kalde dit statement lige, hvad du vil ... $herbert_leopold_maximillian_van_der_schwandvogel, hvis du føler for det. Noget lidt mere sigende ville dog være hensigtsmæssigt =)
Derfor bruger man ofte $stmt i eksempler - ligesom en hurtig * i SQL-sætningen, selvom man ville bruge de enkelte feltnavne i virkeligheden.
Du kan f.eks:
<?php $db = new mysqli('server', 'brugernavn', 'kodeord', 'database');
$stmt_1 = $db->prepare("SELECT `name`, `bio` FROM `table` WHERE `age` = ?"); $stmt_2 = $db->prepare("SELECT `name`, `sex` FROM `table_2` WHERE `id` = ?"); if($stmt_1) { // Bind your variable to replace the ? $stmt_1->bind_param('i', $age);
// Set your variable $age = 32;
// Execute query $stmt_1->execute();
// Bind your result columns to variables $stmt_1->bind_result($name, $bio);
// Fetch the result of the query while($stmt_1->fetch()) { echo $name . ' - ' . $bio; // John Doe - Unknown... } }
if($stmt_2) { // Bind your variable to replace the ? $stmt_2->bind_param('i', $userid);
// Set your variable $userid = 1235;
// Execute query $stmt_2->execute();
// Bind your result columns to variables $stmt_2->bind_result($name, $sex);
// Fetch the result of the query while($stmt_2->fetch()) { echo $name . ' - ' . $sex; // John Doe - Unknown... } } $stmt_1->close(); $stmt_2->close(); ?>
okay super :) hvordan laver jeg så et kald til, f.eks. bio eller sex fra en anden fil? det er vel ikke sådan at jeg skal smide ovenstående kode ind i en funktion og kalde den vel?
Kunne også godt tænke mig at vide hvordan man bruger den lidt mere fleksibelt. kan ikke helt regne det ud. Altså bruge den kode jeg har i sql.php med et id som komme fra fx. index.php, altså som en slags parameter. hvordan får man sådan en med "udefra"?
Selvtak. Når du har fyret execute af, kan du også hente et result objekt og f.eks. bruge fetch_assoc, så det kommer til at ligne det gamle API lidt mere:
// Execute query $stmt_1->execute(); // Get a result object $res = $stmt_1->get_result(); // Create array to hold the rows $aRows = array(); // Fetch the rows as associative arrays while ($row=$res->fetch_assoc()) { $aRows[] = $row; } // Free result $res->free(); // Close statement $stmt_1->close();
Hmm den skal jeg lige kigge nærmere på tror jeg :b
prøvede lige at få udskrevet en liste af data ud, men kan umiddelbart ikke få det til at fungerer. Har prøvet at skrive et par forskellige ting i index.php som går udfra sql.php med det array eksempel du skrev tidligere i $22. Har lige nu:
okay det er selvf. fordi id står statisk til "1" i sql.php: ...
$stmt_1 = $db->prepare("SELECT `email`, `password` FROM `users` WHERE `id` = ?"); if($stmt_1) { // Bind your variable to replace the ? $stmt_1->bind_param('i', $id);
// Set your variable $id = 1;
...
hvordan får man den til at kunne ændre sig dynamisk?
hmm det er måske lidt for meget off-topic nu, i forhold til overskriften :) Har også fundet en god tutorial der tager det helt fra bunden så jeg opretter bare et nyt spørgsmål herinde hvis render ind i problemer igen. Lukker tråden nu.
Den øgede sikerhed er kun én god grund til at bruge prepared statements. En anden er, at databasen 'kompilerer' dit statement, så du kan tilgå det samme statement mange gange med forskellige parametre (i virkeligheden 'argumenter', men lad det ligge).
I det gamle API skulle databasen køre hele processen, hvergang den blev kaldt med en query. Det svarer til aldrig at skrive en funktion i PHP. I stedet skriver man den fulde kode om og om igen, hvergang man ellers ville kalde en funktion.
Prepared statements svarer derimod til at skrive en funktion og efterfølgende kalde den mange gange med forskellige argumenter.
Det gør prepared statements marginalt langsommere ved enkeltkald, men dramatisk meget hurtigere ved mange kald med samme statement.
Og når du så er færdig med alt dette, bør du helt sikkert kikke på, hvad jeg skrev i #16 *o)
Uden effektiv styring af dine databasebrugere - altså det brugernavn/password du skriver, når du skriver $db = new mysqli(...); - vil det mindste lille sikkerhedshul kunne have enorme og katastrofale følger.
Med fornuftig styring af DB-brugere kan du have temmelig store sikkerhedshuller uden nogen alvorlige skader til følge.
Alt det, du laver nu, er rigtig fint - men kan være uden særlig stor betydning, hvis du ikke også tager dig af #16
#30 Ja kan godt se at det giver bedst mening med mysqli. Er også i fuld sving med at sætte mig ind i det :)
Har lige prøvet med et eksempel der skulle bruge en $_GET fra url'en. Bare for at prøve lidt forskellige ting. Gjorde sådan her:
$specList = $db->prepare('SELECT id, email, firstname, lastname FROM users WHERE id=?') or die ('Could not prepare the users info'); $specList->bind_param('i', $_GET['id']); $specList->bind_result($id, $email, $firstname, $lastname); $specList->execute();
print $email;
men den smider bare min egen fejlmedd. lige tilbage igen :/ (Could not prepare the users info)
Har forbundet til min db i en fil ved siden af, eller skal man gøre det igen og igen?
hej igen, jeg har lige været afsted på ferie så har ikke haft tid til at skrive tilbage. Har lige siddet og roddet lidt med det og synes jeg er ved at have styr på det.. har bare et sidste spørgsmål: skal man "connecte" på ny hver gang man lave et nyt prepared statement?? altså skrive dette igen hver gang:
$mysqli = new mysqli('localhost', 'root', '', '------') or die ('Could not connect to the database');
det bliver bare lidt besværligt når jeg på et tidspunkt vil lægge det ud på nettet da jeg så skal ændre pass, db navn osv. til forbindelsen en masse forskellige steder.
Så har du en dårlig struktur. Dine MySQL-forbindelses informationer bør stå ét sted i en inkluderet fil sammen med alle dine andre konfigurationer - f.eks. i et array eller object.
Derudover bør du have en funktion, som forbinder til databasen og returnerer forbindelsen, når den bliver kaldt med de fornødne database informationer som argument.
Tag det som en kærkommen mulighed for at få lavet en ordentlig struktur. Tro mig: Besværet med dette er for intet at regne i sammenligning med, hvad du meget let kommer ud for med det gamle API - skulle en eller anden ønske at lave 'pjatmås' med dig *o)
#37: Nej, hvergang! Du skal sørge for at styre, hvad dine brugere kan gøre i databasen. Den MySQL-bruger, man logger ind med, må kun have rettigheder til det, brugeren forventes at have brug for i den givne situation.
Når jeg bare læser sider på et site, må den MySQL-bruger, som henter data til siderne, ikke kunne udføre f.eks. INSERT, UPDATE, ALTER eller DROP. Ellers er der sat vand over til unødige problemer, hvis jeg mod forventning skulle være smartere end du er - og alligevel får lusket en sær forespørgsel igennem =)
I en sikker applikation er det derfor nødvendigt at have forskellige MySQL-brugere til forskellige opgaver - og derfor ikke nøjes med at forbinde til databasen én gang.
Kun så længe, der er tale om en række af samme type forespørgsler, kan man bruge samme forbindelse
#olebole: havde også tænkt mig at have al sql stående i en fil. det er bare det med "connect" delen jeg ikke er sikker ved. Måden jeg har gjort det hidtil er at lave en funktion som tilslutter db'en og den har jeg så kaldt når jeg fik brug for den.. det ser bare ikke ud til at fungere i denne her sammenhæng..
forresten også lukke sin forbindelse igen efter at have lavet "new mysqli"??
har lavet funktionen connect i en fil for sig selv, som jeg inkluderer og derefter kalder. er det ikke sådan det skal gøres? eller er jeg gået helt galt i byen ? :)
function connect() { $mysqli = new mysqli('localhost', 'root', '', '-----') or die ('Could not connect to the database'); }
hvis du har links til nogle gode tutorials der dækker det meste må du meget gerne smide dem her, synes ikke jeg har kunne finde nogle der går rundt om det hele, kun korte introduktioner :/
Sludder! Den returnerer da vist kun en boolean! Den er heller ikke særlig fiks, da du skal have en funktion for hver af dine MySQL-brugere. Gør hellere sådan:
function connect($host, $user, $pass, $db) { $mysqli = new mysqli($host, $user, $pass, $db); if (mysqli_connect_errno()) die ('Could not connect to the database'); return $mysqli; }
Selvtak. Det er i hvertfald altid lidt lettere for svarerne at komme tilbage til en kortere tråd og få 'læst op' på problemet *o)
Synes godt om
Ny brugerNybegynder
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.