« 1 2 »
Autor Zpráva
jakre
Profil
Zdravím místní odborníky,

potřeboval bych nápad, jak zrealizovat jednoduchý rezervační systém. V bodech jsem shrnul, jak by měl fungovat:

1) Na hlavní stránce bude nutnost zadat nějaké vstupní informace (např. jméno, sedadlo, stůl).
2) Výstupem bude stránka s nějakým tokenem (např. htttp://domena.cz/rezervace.php?token=XXX-YYY-ZZZ), ale po odeslání formuláře z 1) se vygeneruje QR kód, který na tuto stránku směřuje.
3) Na stránce s tokenem budou informace z databáze uložené z 1) (tzn. jméno, sedadlo, stůl).

V praxi to bude fungovat tak, že se přetče QR kód a načte se stránka, kde se dozvím jaký ke vstupence patří stůl. Pak ale potřebuji, abych mohl ten token "znefunkčnit" - důležité je, aby to bylo možné během několika sekund.

Vím, jak část z toho udělat, ale byl bych rád za co nejjednodušší řešení.

Předem díky za jakékoli nápady,
jakre
Keeehi
Profil
jakre:
Pak ale potřebuji, abych mohl ten token "znefunkčnit" - důležité je, aby to bylo možné během několika sekund.
Tak není po problém, aby se stránka s tokenem dala načíst jen jednou a aby platil jen nějaký omezený čas. Standardně to takto funguje u jednorázových odkazů pro změnu hesla.

Nějak v tom celém nevidím problém. S čím si nevíš rady?
jakre
Profil
Keeehi:
Ten QR kód bude místo vstupenky a pokud by se po prvním načtení token automaticky deaktivoval, tak by vstupenka byla neplatná (např. když si kód přečte uživatel místo pořadatele).
juriad
Profil
Tabulka rezervací:
- ID
- jméno
- email
- sedadlo
- stůl
- datum
- token
- stav (enum: platná, zrušená, použitá)
- datum_zmeny

Při vytvoření rezervace přesměruješ člověka na stránku rezervace.php?token=XXX-YYY-ZZZ, a pošleš mu e-mail s tímto odkazem a s PDF v příloze, které bude obsahovat detaily rezervace včetně QR kódu.
QR kód bude obsahovat URL té stránky. Důležité je, navzdory tomu co tvrdí Keeehi, aby stránka obsahovala read-only informace, které jsou užitečné pro klienta.

Ty při vstupu do objeku naskenuješ QR kód, ale z URL si vyzobneš jen ten token a použiješ jinou stránku kontrola.php?token=XXX-YYY-ZZZ, která automatiky označí datum_zmeny na aktuální datum (a čas), pokud je stav=platná, jinak nahlásí chybu.
jakre
Profil
Děkuji za návrhy.

juriad:
naskenuješ QR kód, ale z URL si vyzobneš jen ten token a použiješ jinou stránku kontrola.php?token=XXX-YYY-ZZZ
Zřejmě jsem hloupý, ale nedochází mi, jak bych si token "vyzobnul".

označí datum_zmeny na aktuální datum (a čas), pokud je stav=platná, jinak nahlásí chybu
Z toho také nejsem moc moudrý.
Keeehi
Profil
jakre:
Ta url může být pořád stejná. Pokud bude uživatel nepřihlášen (návštěvník) bude to jak píše juriad, jen read only zobrazovač dat z databáze. Pokud bude uživatel na stánku přihlášen (pořadatel), při načtení si script zase načte ten daný záznam z databáze a zobrazí ho pořadateli. Kromě toho však taky změní stav z platná na použitá.

Co se bezpečnosti týče, tak token musí být náhodný a dostatečně dlouhý. Jinak by mohl být člověk schopen uhodnout token jiných lidí a tak si vygenerovat jejich vstupenku.
juriad
Profil
Máš nějakou čtečku QR kódů; nevím, co to je za zařízení, ale snad bude umět vrátit obsah QR kódu jako text. V tomto případě vrátí:
http://domena.cz/rezervace.php?token=XXX-YYY-ZZZ
Ty si z toho regexy/substringem/čímkoli vybereš jen ten token:
XXX-YYY-ZZZ
A pak zobrazíš stránku:
http://domena.cz/kontrola.php?token=XXX-YYY-ZZZ


Na stránce kontrola.php podle parametru token:
1) provedeš UPDATE:
UPDATE rezervace SET stav='použitá', datum_zmeny=NOW() WHERE stav='platná' AND token='XXX-YYY-ZZZ'
Pokud počet změněných řádků je 1, tak vypíšeš, že "Vstupenka je v pořádku a byla změněna na použitou.
V opačném případě nahlásíš chybu (třeba změníš pozadí stránky na červené).
2) načteš z databáze podrobnosti o rezervaci pomoci obyčejného SELECTu a zobrazíš je na stránce.

Keeehi:
Hm, asi bych raději vyhradil zvláštní stránku pro toto označování, protože se ti může stát následující: Zavolá ti klient, že mu nejde vytvořit rezervace, nadiktuje ti údaje a ty vytvoříš rezervaci. Jsi přesměrován na stránku rezervace.php, a protože jsi přihlášený jako admin, tak se rezervace okamžitě použije.
Tato zvláštní stránka by měla být použitá jen ze zařízení, které ovládá kontrola u vstupu do objektu.
jakre
Profil
juriad:
Máš nějakou čtečku QR kódů; nevím, co to je za zařízení, ale snad bude umět vrátit obsah QR kódu jako text.
Spíš jsem počítal s aplikací do mobilu, ale to pak nebude tak jednoduché.
Keeehi
Profil
juriad:
Jsi přesměrován na stránku rezervace.php
1) Proč by měla aplikace fungovat tak hloupě, že by v ní nešla vytvořit rezervace? Když bych ji vytvářel, tak ji snad vytvořím tak, aby se toto nestalo.
2) Nevím jak jakre chce mít ten systém rozsáhlý, ale vůbec by nebylo od věci tam mít více rolí. Ten pořadatel co kontroluje vstupenky může být klidně nějaký brigádník a tomu nechceš dát veškerá práva k aplikaci. A zase nějaká pokladní, která bude tu rezervaci vytvářet vůbec nemusí mít práva, aby když navšítí tu stránku, aby zneplatnila vstupenku.


jakre:
Spíš jsem počítal s aplikací do mobilu, ale to pak nebude tak jednoduché.
Zas tak složité to není.

Protože s tím mám zkušenosti, tak bych jen chtěl upozornit na to, že pak na místě musí být dobré světelné podmínky. My jsme takhle četli čárové kódy a měli jsme s tím problémy. Pokud se použije k tomu zařízení přímo určené, na světelných podmínkách pak prakticky nezáleží.
jakre
Profil
Abych to upřesnil, jde o vstupenky na vánočák. Důvodem řešení online cestou je snížení rizika, znemožnění, padělání vstupenky. QR čtení vstupenky mě napadlo pro rychlé zpracování, aby se netvořily dlouhé fronty - bežně totiž stačí roztrhnout vstupenku. Prodával by se v podstatě ten QR kód, který by si návštěvníci museli vytisknout (jednou jsem kód zkoušel načíst z displeje mobilu, ale bohužel to nefungovalo). Takže i když je bude prodávat několik různých lidí, bude stačit jedna role a ta pořadatelská, kde se bude zneplatňovat.

Co se stane, když ten kód někdo vytiskne víckrát? Dostane se tam pak pouze ten, kdo půjde první, ne?

V praxi s podobným řešením nemám zkušenosti a nemohu si dovolit zhotovit něco, co by nebylo spolehlivé.
xaverista
Profil
jakre:
Co se stane, když ten kód někdo vytiskne víckrát? Dostane se tam pak pouze ten, kdo půjde první, ne?
Ano, kdyby někdo vytiskl vstupenku 2x nebo z nějakého důvodu by někdo uhodl kód vstupenky, tak se tam dostane pouze 1. Člověk viz kód [#7] od juriad

Keeehi:
tak bych jen chtěl upozornit na to, že pak na místě musí být dobré světelné podmínky
V tomto případě bych ještě doporučil, aby byl kód, který je uchován pod QR kódem byl navíc vytisknut např. pod ním na vstupence, aby kdyby náhodou s tímto vznikly problémy jsi schopen jeho kód zadat k verifikaci ručně
jakre
Profil
xaverista:
Díky.

Zatím mám následující tabulku (obrázek) podle [#7] juriad:

CREATE TABLE `XXXXXXXXXXX`.`Rezervace` ( `id` INT NOT NULL , `jmeno`VARCHAR(120) NOT NULL , `email` VARCHAR(254) NOT NULL , `sedadlo` VARCHAR(3)NOT NULL , `stul` VARCHAR(2) NOT NULL , `datum` DATE NOT NULL , `token`VARCHAR(14) NOT NULL , `stav` ENUM('platna','zrusena','pouzita') NOT NULL ,`datum_zmeny` DATE NOT NULL ) ENGINE = InnoDB;

a formulář (ukázka).

<form action="rezervace.php" method="post">
        <p><label>Jméno: </label><input type="text" name="jmeno"></p>
        <p><label>Email: </label><input type="text" name="email"></p>
        <p>Sedadlo: 
            <label><input type="radio" name="sedadlo" value="1"> 1</label>
            <label><input type="radio" name="sedadlo" value="2"> 2</label>
        </p>
        <p>Stůl: 
            <label><input type="radio" name="stul" value="1"> 1</label>
            <label><input type="radio" name="stul" value="2"> 2</label>
        </p>
        <input type="submit" value="Rezervovat">
</form>

Nevím si zcela rady s PHP kódem, ale zbouchal jsem toto:

<?php
$link = mysqli_connect("*", "*", "*", "XXXXXXXXXXX"); // *Upraveno
if($link === false){
    die("ERROR: Could not connect. " . mysqli_connect_error());
}
 
$jmeno = mysqli_real_escape_string($link, $_POST['jmeno']);
$email = mysqli_real_escape_string($link, $_POST['email']);
 
$sql = "INSERT INTO Rezervace (jmeno, email) VALUES ('$jmeno', '$email')";
if(mysqli_query($link, $sql)){
    echo "Records added successfully.";
} else{
    echo "ERROR: Could not able to execute $sql. " . mysqli_error($link);
}
 
mysqli_close($link);
?>

Po odeslání formuláře se objeví tento záznam a po přidání dalších mají všechny stejnou hodnotu pole id. Nevím však, jak do databáze zapsat hodnoty ratio inputů a jak pokračovat dále.


juriad:
Z jakého důvodu jsi mi navrhnul pole datum? Jestli jde o datum konání, tak není důležité, jelikož je akce pouze jednorázová.
juriad
Profil
jakre:
id bude PRIMARY KEY AUTO_INCREMENT
datum bude DATETIME (a možná i DEFAULT CURRENT_TIMESTAMP)
datum_zmeny nebude NOT NULL
stav může mít DEFAULT 'pltana'

Datum je datum založení rezervace. Pokud nemáš vyloženě důvod, proč to nedělat, ukládej si datum i s časem - typ DATETIME.

Při INSERTu musíš vložit všechny povinné položky:
jmeno, email, sedadlo, stul, datum (pokud nemá DEFAULT), token, stav (pokud nemá DEFAULT)

Token bych vytvářel asi pomocí:
stackoverflow.com/a/13733588/4052811
Změň abecedu jen na posloupnost velkých písmen; použij jich asi 9 (když je to jednorázová akce).
jakre
Profil
juriad:
Děkuji. Teď už se data zapisují správně.

datum_zmeny nebude NOT NULL
Ve výchozím stavu jsou u mě všechny řádky nenulové, má to tak být?

Změň abecedu jen na posloupnost velkých písmen; použij jich asi 9 (když je to jednorázová akce).
Myslím si, že je vhodnější použít složitější token, aby se nedal jednoduše odhadnout. Navíc k jeho uchování chci použít QR kód.
juriad
Profil
jakre:
datum_zmeny byl navržen tak, že uchovává, kdy došlo ke změně stavu; na začátku by tedy měl být NULL.

9 znaků; to je 26^9 je 5429503678976 možností. Předpokládejme, že v databázi je 1000 rezervací. I kdyby někdo zkusil miliardu možností, tak stále má pravděpodobnost úspěchu jen 18 %.
A jelikož jediný způsob, jak zjistit, zda token existuj nebo ne, je vyzkoušet jít na stránku rezervace.php?token=XXX-YYY-ZZZ, myslím, že by sis všimnul miliardy přístupů. :-)
jakre
Profil
juriad:
datum_zmeny byl navržen tak, že uchovává, kdy došlo ke změně stavu; na začátku by tedy měl být NULL.
Aha, ten tedy využiju později?

9 znaků; to je 26^9 je 5429503678976 možností.
To je pravda. Když už bych to tedy omezoval, nechal bych to na 14ti místném čísle (to bude jednodušší zadat, když selže QR kód).

Mimochodem, nepochopil jsem druhou část (tu pod čarou) postupu z [#7] juriad, vysvětlí mi to někdo konkrétněji, prosím?
xaverista
Profil
jakre:
Mimochodem, nepochopil jsem druhou část
když přistoupíš na script kontrola.php vy táhneš si z URL http://domena.cz/kontrola.php?token=XXX-YYY-ZZZ token pomocí $_GET['token'] a vykonáš dotaz, který ti tam napsal, tedy:
UPDATE rezervace SET stav='použitá', datum_zmeny=NOW() WHERE stav='platná' AND token='XXX-YYY-ZZZ'
a poté pomocí fce mysqli_affected_rows zjistíš, kolik záznamů (vstupenek) jsi updatoval => správně by jsi měl updatovat POUZE 1 záznam, tímpádem byla vstupenka ještě nepoužita, a zároveň je token platný

a) Pokud ti fce mysqli_affected_rows vrátí jinou hodnotu, nejspíše se něco pokazilo (tedy token není platný nebo vstupenka byla již použita) a tímpádem můžeš vypsat na obrazovku, že vstupenka není platná nebo již byla použita nebo můžeš změnit barvu pozadí stránky na červenou, tak jak by jsi přišel k turniketu a zobrazil by se ti tam např.: červený křížek, tzn. nemáš v pořádku ticket

b) Pokud ti ta fce vrátí hodnotu 1, znamená to, že změna proběhla v pořádku a ticket je ještě stále platný (nepoužit) a zároveň souhlasí i token vstupenky a na obrazovku si můžeš vypsat údaje o rezervaci, abys jim mohl třeba říct, kde se jejich stůl nachází
jakre
Profil
xaverista:
Díky za vysvětlení. Takže návod od juriada slouží ke změně stavu (platnosti) vstupenky, chápu-li dobře. Já jsem se ale seknul ve stavu, kdy:

1) formulář odešle data a vrátí QR kód s tokenem (např. kontrola.php?token=DWEYOIAQ27JAYP),
2) skript kontrola.php zkontroluje, jestli byl token zadán a jestli je dlouhý 14 znaků, v případě, že ano, vypíše ho.

Potřeboval bych, aby se na základě toho tokenu dohledaly informace z databáze (jméno, email, atd.) a vypsaly se, ale nevím, jak to udělat.
xaverista
Profil
jakre:
Potřeboval bych, aby se na základě toho tokenu dohledaly informace z databáze (jméno, email, atd.) a vypsaly se, ale nevím, jak to udělat.
<?php 
    $sql = "SELECT `id`, `jmeno`, `email`, `sedadlo`, `stul` FROM Rezervace WHERE token='" . $token . "'";
    $result = mysqli_query($link, $sql);
    while($f = mysqli_fetch_array($result)){
        echo "ID: " . $f['id'] . "<br />";
        echo "jmeno: " . $f['jmeno'] . "<br />";
        echo "email: " . $f['email'] . "<br />";
        echo "stul: " . $f['stul'] . "<br />";
        echo "sedadlo: " . $f['sedadlo'] . "<br />";
    }
    mysqli_close($link);
 ?>

netestováno a nezapomeň na zabezpečení dotazu ještě :-)
jakre
Profil
xaverista:
Funguje to, děkuji. Jak vypíšu nějakou hlášku, když se token nenajde?

nezapomeň na zabezpečení dotazu ještě
K zapisování používám něco ve stylu $jmeno = mysqli_real_escape_string($link, $_POST['jmeno']);, jak ošetřím výpisy?


Teď zbývá dořešit, jakým způsobem měnit platnost vstupenky. Teď to funguje, jak jsem pospal výše v [#18] a QR kód odkáže na stránku s informacemi o vstupence na základě tokenu. Kde ale vezmu QR kód já, jako pořadatel, jehož načtením změním provedu ověření z [#7] juriad a změním platnost vstupenky?
xaverista
Profil
jakre:
jak ošetřím výpisy?
např.: pro jméno:
htmlspecialchars($f['jmeno'], ENT_QUOTES);

Kde ale vezmu QR kód já, jako pořadate
Tak na toto si budeš muset udělat "administrační sekci" kde si jako přihlášený uživatel s rolí admin vypíšeš z DB všechny vstupenky a uděláš si nějakou stránku na editaci vstupenek, můžeš si tam dát, že budeš moci editovat všechny informace (jmeno, email, stul, sedadlo, datum atd.)
Lonanek
Profil
jakre:
jak ošetřím výpisy?
htmlspecialchars()
Domnívám se, že v [#19] je výpis pomocí cyklu zbytečný, protože dotaz by měl vrátit pouze jeden záznam, pokud ne, pak je něco špatně.
xaverista
Profil
Lonanek:
Domnívám se, že je výpis pomocí cyklu zbytečný
Ano to jsem si neuvědomil :-) tímpádem tento výpis můžeš použít pro výpis všech vstupenek zákazníků s akorát trochu poupraveným dotazem:
$sql = "SELECT `id`, `jmeno`, `email`, `sedadlo`, `stul` FROM Rezervace";
jakre
Profil
xaverista:
Děkuji pěkně.

Tak na toto si budeš muset udělat "administrační sekci"
To mi přijde moc složité. Mně nějaké řešení navrhoval [#7] juriad, ale vzhledem k tomu, že čtečkou je mobil to asi nepůjde. Na což reagoval Keeehi:
jakre:
„Spíš jsem počítal s aplikací do mobilu, ale to pak nebude tak jednoduché.“
Zas tak složité to není.

Já si totiž podle mě z QR kódu nemohu mobilní čtečkou vytáhnout token, zkontrolovat ho apomocí skriptu na jiné adrese a změnit vstupence platnost.

Lonanek:
Domnívám se, že v [#19] je výpis pomocí cyklu zbytečný
Mně přijde, že to zas tak nevadí. Zdrojový kód nikdo nevidí :-)
Keeehi
Profil
jakre:
Já si totiž podle mě z QR kódu nemohu mobilní čtečkou vytáhnout token, zkontrolovat ho apomocí skriptu na jiné adrese a změnit vstupence platnost.
Pokud na to vytvoříš celou mobilní aplikaci, tak to není problém. Tvoje aplikace zavolá aplikaci pro čtení qr kódů a ta až nějaký uvidí, tak jí z něho vrátí data. No a v té tvé aplikaci si už s řetězci ůžeš hrát jak chceš. Pak by v QR kódu ani nemusel být celý odkaz, jen ten token. Pokud bys ale nevytvářel vlastní aplikaci, ale jen přešel na odkaz, co by se v kódu skrýval, pak ano, jeho adresu bys těžko měnil.
jakre
Profil
Keeehi:
Právě proto mě nic nenapadlo, myslel jsem, že víš o něčem jednoduchém, když jsi psal, že to zas tak složité není - pro mě je to španělská vesnice.
xaverista
Profil
jakre:
Možná by se hodilo toto, možná tam najdeš to, co hledáš :-) avšak je to placené nebo by se mohly využít appky které ti do inputu vepišou text, který ty verifikujes
jakre
Profil
xaverista:
Mockkrát děkuju, to je ono.

Ještě mám otázku k tomu, jak vypsat nějakou hlášku, když se pro daný token v databázi nic nenajde? Tedy jakou konkrétně podmínku mám použít?
Keeehi
Profil
jakre:
Pokud místo while použiješ if, tak tu hlášku napíšeš už jen do else větve.
jakre
Profil
Potřeboval bych prosím poradit ještě s jedním kódem. Vytvářím skript na ověření platnosti vstupenky podle [#7] juriad, ale kód nefunguje:

if (isset($_GET['token']) && strlen($_GET['token']) > 0) {
    
    if (isset($_GET['token']) && strlen($_GET['token']) == 14) {
    $token = $_GET['token'];
        
        $link = mysqli_connect("*", "*", "*", "*"); // *Zde je to v pořádku
if($link === false){
    die("<strong>CHYBA: Nelze se připojit k databázi.</strong> " . mysqli_connect_error());
}
        $sql = "UPDATE Rezervace SET stav='použitá', datum_zmeny=NOW() WHERE stav='platná' AND token='" . $token . "'";
        printf("Affected rows (UPDATE): %d\n", $mysqli->affected_rows);
    $result = mysqli_query($link, $sql);
    
        
    mysqli_close($link);
    }
    
    else{echo '<strong>Token nebyl rozeznán.</strong>';}
    
}
else{echo '<strong>Token nebyl zadán.</strong>';}

Při zadání platné vstupenky s existujícím tokenem to vypíše Affected rows (UPDATE): 0 a změny se neprovedou.
« 1 2 »

Vaše odpověď


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm: