LINUXSOFT.cz Přeskoč levou lištu
Uživatel: Heslo:  
   CZUKPL

> Perl (83) - CGI - získávání dat od uživatele

Perl Konečně se dostáváme ke kapitole, která popisuje získávání dat od klienta. Vstup je jedno z důležitých témat webového programování.

13.7.2009 00:00 | Jiří Václavík | Články autora | přečteno 10050×

Co to vstup dat do CGI skriptu vlastně je? Nejprve uveďme, jakou má vstup formu. Můžeme říct, že to je datová struktura podobná hashi. Uživatel pošle serveru dvojice klíč - hodnota. Tyto informace jsou pak s předány CGI skriptu běhěm volání.

Jsou dvě metody, jak může uživatel předávat serveru vstup. Buď pomocí formulářů (metoda POST) nebo je může zakomponovat do URL adresy požadovaného dokumentu. Oběma se budeme postupně zabývat.

Možná je vždy pouze jedna metoda vstupu. Nelze tedy zároveň přijímat zároveň jak formulářová data, tak data z URL. Abychom mohli ve sporných případech určit, který vstup je aktuální, získá CGI skript od serveru proměnnou prostředí REQUEST_HETHOD, ke které v Perlu přistupujeme pomocí $ENV{"REQUEST_METHOD"}. Metodu vstupu indikuje obsah této proměnné, což je buď řetězec POST nebo GET.

Vstup z formulářů

Data získaná z formulářů čteme ze standardního vstupu. Konkrétně, máme-li například formulář se dvěma položkami jmeno a heslo, přečteme ze standardního vstupu řetězec, do kterého budou zakódované položky jmeno a heslo i s hodnotami, které uživatel do formuláře zadal.

Formát vstupního řetězce má obecně tvar klíč1=hodnota1&klíč2=hodnota2&...&klíčn=hodnotan. To znamená, že pro situaci s položkami jmeno a heslo by vypadal získaný řetězec takto: jmeno=jiri&heslo=m0je_hEslo.

Pokud má nějaký parametr vstupního řetězce jako hodnotu seznam, je pro všechny hodnoty tohoto seznamu vytvořena dvojice klíč-hodnota se stejným klíčem. Příkladem může být řetězec check=a&check=b&check=c.

Vstup z URL

Druhou zmiňovanou možností vstupu je získání řetězce zakomponovaného do URL adresy dokumentu. Předání metodou GET spočívá v tom, že za umístění dokumentu zadáme otazník a dále dvojice ve formátu klíč=hodnota oddělené znakem & (ampérsand).

To znamená, že pokud zadáme do WWW prohlížeče jako umístění adresu http://localhost/cgi-bin/skript.cgi?jmeno=jiri&heslo=m0je_hEslo (mimochodem, nešifrované heslo v příkazovém řádku prohlížeče není příliš bezpečné), dostane CGI skript parametry jmeno a heslo metodou GET.

Získaný řetězec parametrů - tedy vše, co je v URL za otazníkem - se nám objeví v proměnné prostředí QUERY_STRING. V CGI skriptu tak můžeme k těmto datům přistupovat z proměnné $ENV{"QUERY_STRING"}.

Dále již postupujeme stejně jako u formulářového vstupu.

Zpracování získaných řetězců

Teď už by neměl být problém pomocí nám dobře známých nástrojů Perlu získat z řetězce hash parametrů. Máme zde dvě drobně překážky.

  1. Rozdělením řetězců spojených znakem & získáme řetězce ve formátu klíč=hodnota. Tyto řetězce na pozici rovnítka opět rozdělíme a získáme tak hash parametrů.
  2. Aby bylo možné přenášet v URL i písmena s háčky a čárkami a také mezery, probíhá již u klienta (ve WWW prohlížeči) konverze těchto znaků. Zkusíme-li zadat do formuláře písmena s háčky, CGI skript je dostane zakódované. Místo slova zpět tak dostaneme zp%ECt. Musíme tak ještě před definitivním uložením do hashe nahradit sekvenci %.. za správný znak. Mezery jsou nahrazovány znakem +.
my %hash;
for (split "&", $retezec){
    my($k, $h) = split "=";
    $h =~ tr/+/ /;
    $h =~ s/%(..)/chr hex $1/ge;
    $hash{$k} = $h;
}

Nyní máme v proměnné %hash požadované páry parametr-hodnota, se kterými můžeme pohodlně pracovat.

Poznámka - Úplně jsme vynechali parametry se seznamovou hodnotou. Prozatím se jim nebudeme věnovat.

Konkrétní příklad obsluhy formulářů

Jedno z nejčastějších užití CGI je zpracovávání dat, které uživatel zadal do formuláře. Na základě těchto dat mohou být například přidány záznamy do databáze nebo můžeme naopak z databáze požadovaná data získat.

Již víme, jak získat formulářová data. Máme tedy všechny potřebné znalosti k tomu, abychom si uvedli první ukázku programu, jež bude vstupu od uživatele využívat.

Vytvoříme si přihlašovací skript, který na se základě do formuláře zadaného uživatelského jména a hesla otáže databáze, zda takový uživatel se zadaným heslem existuje. Pokud zjistí, že tento uživatel skutečně existuje, zobrazíme z databáze zprávu. V opačném případě přesměrujeme na stránku, která vygeneruje chybu.

Ze všeho nejdříve bude třeba navrhnout datovou základnu. Otevřeme tedy řádkového databázového klienta, vytvoříme databázi s názvem projekt a zde umístíme tabulku users s následující strukturou. vložíme také jeden testovací záznam.

create table users (
    id int not null primary key auto_increment,
    username varchar(60) not null,
    md5passwd varchar(32) not null,
    zprava varchar(255) not null
);
insert into users (user, md5passwd, zprava) values ('pokus', 'fde27fdce626407e9ad040b7bb017882', 'TAJNA ZPRAVA');

Toto je zdrojový text pro databázový systém MySQL. Chcete-li použít například Postgres, pak místo druhého řádku napište id serial primary key,.

Další poznámka bude směřovat k uložení hesla. Do databáze neukládáme čisté heslo (pokus), ale jeho md5-hashovanou verzi. Použití hashovacího algoritmu nám zaručí, že i kdyby se potenciální útočník dostal do databáze, získá pouze data, ale nikoliv hesla. My heslo nepotřebujeme, protože budeme porovnávat pouze výsledek funkce md5.

Je třeba dodat, v roce 2004 byly nalezeny první kolize algoritmu md5 (to jest více řetězců se stejným hashem) a nyní je již možné provádět inverzní operaci k hashování na běžném počítači do několika sekund. Pro bezpečnější uložení hesel lze použít některý z rodiny algoritmů SHA-2, u kterých ještě žádná kolize objevena nebyla.

Nyní musíme vytvořit dva soubory. Prvním z nich bude obyčejný HTML formulář, který bude data odesílat CGI skriptu, což bude druhý soubor.

Soubor s formulářem je čisté HTML bez jakýchkoliv dynamických prvků. Dále budeme pracovat s níže uvedeným formulářem. Uložíme ho například jako formular.html do kořenového adresáře Apache. Fyzicky tedy bude ležet v /usr/local/apache2/htdocs a do prohlížeče budeme zadávat http://localhost/formular.html.

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
  <title>Log in</title>
</head>
<body>

<form action="/cgi-bin/login.cgi" method='POST'>
    Uživatelské jméno: <input type='text' name='username'><br>
    Heslo: <input type='text' name='heslo'><br>
    <input type='submit' name='akce' value='Log in'>
</form>

</body>
</html>

Dále vytvoříme samotný CGI skript, který bude formulář obsluhovat. Jak vidíme z výše uvedeného HTML kódu, jako umístění CGI skriptu jsme zvolili /usr/local/apache2/cgi-bin/login.cgi.

Úvod skriptu login.cgi je obvyklý. Protože již víme, že budeme používat databázi, importujeme hned i modul DBI. Dále vytvoříme hash parametrů a budeme načítat data.

#!/usr/bin/perl
use strict;
use DBI;

#do proměnné %hash uložíme formulářová data
my %hash;
for (split "&", <STDIN>){
    my($k, $h) = split "=";
    $h =~ tr/+/ /;
    $h =~ s/%(..)/chr hex $1/ge;
    $hash{$k} = $h;
}

Nyní se musíme dotázat databáze na správnost uživatelem zadaných údajů. Podle tohoto kritéria se bude odvíjet tělo generovaného dokumentu. Musíme ošetřit případy selhání pokusu o připojení k databázi a nekorektní zadání údajů. Podle toho, kterou větví se bude program ubírat, uložíme do proměnné $telo tělo dokumentu. Na závěr celý dokument vytiskneme.

Nejdříve se tedy musíme pokusit navázat spojení s databází. Je-li toto spojení neúspěšné, přesměrujeme na CGI skript k tomu určený.

my $telo;
my $dbh = DBI->connect("dbi:mysql:dbname=projekt", "user", "");
if(!$dbh){
    print "Location: error.cgi?cislo_chyby=1\n\n";
}else{
    #sem se program dostane, bude-li navázání spojení k databázi úspěšné
}
$dbh->disconnect;

Nyní již předpokládáme, že jsme se úspěšně spojili s databází. Dále se musíme zamyslet nad dotazem, který jí položíme. Potřebujeme zjistit hashované heslo a zprávu. Budeme předpokládat, že existuje vždy jeden uživatel stejného jména nehledě na velikost písmen.

    my $q = $dbh->prepare("SELECT md5passwd, zprava FROM users WHERE UPPER(username)=UPPER(?)");
    $q->execute($hash{"username"});

Aktuální otázka teď zní, zda vůbec zadaný uživatel existuje. To zjistíme podle toho, jestli nám databáze na dotaz pošle nějaké výsledky. Pokud ne, uživatel zadal neplatné uživatelské jméno.

    if(my($md5passwd, $zprava) = $q->fetchrow_array){
        #sem se program dostane, pokud zadané uživatelské jméno je v databázi
    }else{
        $telo = "<h1>Uživatel neexistuje<h1>"
    }

Zbývá ná zkontrolovat poslední věc, kterou je heslo. Tady nastává drobný problém, nebo v databázi máme heslo hashované pomocí md5 a heslo zadané je nešifrované. Jak je porovnat?

V podstatě jedinou možností, kterou máme, je zašifrovat zadané heslo a porovnat vzniklé md5 hashe. Perl má tu výhodu, že existuje archiv modulů CPAN, kde si snadno dohledáme modul Digest::MD5. Pro hexadecimální podobu md5 šifry si do CGI skriptu importujeme funkci md5_hex. Kdyby někdo chtěl použít zmíněný bezpečnější algoritmus, použije modul Digest::SHA2.

use Digest::MD5 qw(md5_hex);

Teď již není nic jednoduššího, než porovnat oba md5 hashe a v případě shody uložit zprávu o úspěchu nebo v opačném případě o neúspěchu.

        if(md5_hex($hash{"heslo"}) eq $md5passwd){
            $telo = "<h1>Úspěch!<h1>\n$zprava";
        }else{
            $telo = "<h1>Nesedí heslo<h1>";
        }

Na závěr vytiskneme HTML dokument.

print << "HTML";
Content-type: text/html; Charset="iso-8859-2"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
    <TITLE>Výsledek</TITLE>
</HEAD>
<BODY>
<font color="#800000">$telo</font>
</BODY>
</HTML>
HTML

Je dobré si uvědomit, jak je to s ošetřováním nakažených dat. Zde k problémům nedošlo.

Pokud si chcete tuto miniaplikaci také vyzkoušet, stahujte zde.

Příklad pro vstup metdodou GET

Abychom si mohli ukázat v praxi, jak pracovat s metodou GET, nechali jsme si v předchozí ukázce CGI skriptu přesměrování v případě chyby databáze. Je-li databáze nedostupná, volá se error.cgi?cislo_chyby=1. Zde je ukázka poněkud jednoduché, leč názorné implementace skriptu error.cgi.

#!/usr/bin/perl
use strict;

my $cislo_chyby = $ENV{"QUERY_STRING"} =~ /cislo_chyby=(\d*)/;
my $chyba;

if   ($cislo_chyby == 1){$chyba = "Chyba při práci s databází";}
elsif($cislo_chyby == 2){$chyba = "Jiná chyba";}
else{                    $chyba = "Neidentifikovaná chyba";}

print << "HTML";
Content-type: text/html; Charset="iso-8859-2"

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<HTML>
<HEAD>
    <TITLE>Výsledek</TITLE>
</HEAD>
<BODY>
<h1>$chyba</h1>
</BODY>
</HTML>
HTML

Verze pro tisk

pridej.cz

 

DISKUZE

Zadani hesla s echem? 14.7.2009 14:20 Roman Vašíček




Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

14.11.2017 16:56 /František Kučera

Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tradičně první čtvrtek před třetím pátkem v měsíci: 16. listopadu od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).


Přidat komentář

12.11.2017 11:06 /Redakce Linuxsoft.cz
PR: 4. ročník odborné IT konference na téma Datová centra pro business proběhne již ve čtvrtek 23. listopadu 2017 v konferenčním centru Vavruška, v paláci Charitas, Karlovo náměstí 5, Praha 2 (u metra Karlovo náměstí) od 9:00. Konference o návrhu, budování, správě a efektivním využívání datových center nabídne odpovědi na aktuální a často řešené otázky, např Jaké jsou aktuální trendy v oblasti datových center a jak je využít pro vlastní prospěch? Jak zajistit pro firmu či jinou organizaci odpovídající služby datových center? Podle jakých kritérií vybrat dodavatele služeb? Jak volit součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně spravovat datové centrum? Jak eliminovat možná rizika? apod.
Přidat komentář

13.9.2017 8:00 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt – tentokrát netradičně v pondělí: 18. září od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

3.9.2017 20:45 /Redakce Linuxsoft.cz
PR: Dne 21. září 2017 proběhne v Praze konference "Mobilní řešení pro business". Hlavní tématy konference budou: nejnovější trendy v oblasti mobilních řešení pro firmy, efektivní využití mobilních zařízení, bezpečnostní rizika a řešení pro jejich omezení, správa mobilních zařízení ve firmách a další.
Přidat komentář

15.5.2017 23:50 /František Kučera
Máš rád svobodný software a hardware nebo se o nich chceš něco dozvědět? Zajímá tě DIY, CNC, SDR nebo morseovka? Přijď na sraz spolku OpenAlt, který se bude konat ve čtvrtek 18. května od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5).
Přidat komentář

12.5.2017 16:42 /Honza Javorek
PyCon CZ, česká konference o programovacím jazyce Python, se po dvou úspěšných ročnících v Brně bude letos konat v Praze, a to 8. až 10. června. Na konferenci letos zavítá např. i Armin Ronacher, známý především jako autor frameworku Flask, šablon Jinja2/Twig, a dalších projektů. Těšit se můžete na přednášky o datové analytice, tvorbě webu, testování, tvorbě API, učení a mentorování programování, přednášky o rozvoji komunity, o použití Pythonu ve vědě nebo k ovládání nejrůznějších zařízení (MicroPython). Na vlastní prsty si můžete na workshopech vyzkoušet postavit Pythonem ovládaného robota, naučit se učit šestileté děti programovat, efektivně testovat nebo si v Pythonu pohrát s kartografickým materiálem. Kupujte lístky, dokud jsou.
Přidat komentář

2.5.2017 9:20 /Eva Rázgová
Putovní konference československé Drupal komunity "DrupalCamp Československo" se tentokrát koná 27. 5.2017 na VUT FIT v Brně. Můžete načerpat a vyměnit si zkušenosti z oblasti Drupalu 7 a 8, UX, SEO, managementu týmového vývoje, využití Dockeru pro Drupal a dalších. Vítáni jsou nováčci i experti. Akci pořádají Slovenská Drupal Asociácia a česká Asociace pro Drupal. Registrace na webu .
Přidat komentář

1.5.2017 20:31 /Pavel `Goldenfish' Kysilka
PR: 25.5.2017 proběhne v Praze konference na téma Firemní informační systémy. Hlavními tématy jsou: Informační systémy s vlastní inteligencí, efektivní práce s dokumenty, mobilní přístup k datům nebo využívání cloudu.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

18.9.2017 14:37 / Rojas
high security vault

15.9.2017 7:33 / Wilson
new zealand childcare jobs

31.8.2017 12:11 / Jaromir Obr
Re: ukůládání dat ze souboru

30.7.2017 11:12 / Jaromir Obr
Národní znaky

27.7.2017 12:24 / Jaromir Obr
Cteni/zapis

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2017) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze