Autor Zpráva
maks
Profil
Ahoj,
tvořím aplikaci, ve které je nutný zabezpečený přístup (klasický login). Mám však problém s přeměrováním na přihlašovací stránku, pokud nejsem přihlášen.

Třeba v Chrome to funguje dobře, avšak FF se zasekne a nepřesměruje se (stále jakoby načítá stránku).

Kód na přihlášení funguje, ten je v pořádku (pro jistotu jej přikládám):
if (isset($_POST['submit_login'])) {
	if (isset($_POST['login'], $_POST['password'])) {
		$login = "SELECT login, rights
					FROM users
					WHERE login = '" . $_POST['login'] . "'
						AND pass = '" . md5($_POST['password']) . "'";
		$login = mysql_query($login);

		if (mysql_num_rows($login) == 1) {
		    $row = mysql_fetch_row($login);
		    
			$_SESSION['user'] = $row[0];
			$_SESSION['rights'] = $row[1];
			$_SESSION['loged'] = 'yes';
			header("location: " . $SERVER . "admin/index.php");
		} else {
			$error = "Přihlášení se nezdařilo. Zkontrolujte, prosím, zda jste zadali správné přihlašovací jméno a heslo.";
		}
	} else {
		if (!isset($_POST['login']))
			$error = "Vyplňte, prosím, uživatelské jméno.";
		if (!isset($_POST['password']))
		    $error = "Vyplňte, prosím, heslo.";
	}
}


Před toto jsem chtěl dát podmínku pro přesměrování na přihlašovací stránku - tzn. nejsem přihlášen a zadám URL z útrob zabezpečeného obsahu, přesměruje mě to na přihlášení. Zajímavé je, že pokud tuto adresu zadám i ve FF poprvé, přesměrování se provede. Při druhém pokusu FF něco načítá (a nenačte do konce).

if (!isset($_SESSION['loged']) and substr($_SERVER['REQUEST_URI'], -6) != "login/") {
	//pokud není nastaveno sessiona a nejsem na přihlašovací stránce, přesměruj. TADY JE CHYBA
	header("location: " . $SERVER . "admin/login/");
}


Děkuji za nakopnutí, čím by to mohlo být.
divadlo kokoko
Profil *
Zdravím.
Tvůj skript jsem nezkoumal,
ale zkusím ti dát pár rad ohledně přesměrování:
* k přesměrování musí dojít před tím, než cokoli zapíšeš na výslednou stránku
* funkce header má další dva nepovinné parametry - doporučuji za 2. dát hodnotu "true" (tzn. přepsat, pokud už byla stejná hlavička nastavena předtím) a jako 3. hodnotu "303" (HTTP kód pro přesměrování stránky)
* v header() - radši bych dal "Location: " s velkým L (nevím - možná je to jedno, ale všude jsem to viděl s velkým)
* cesta za header("Location: musí být kanonizovaná (tj. včetně http(s)://plné.cesta/k/souboru) - alespoň o tom píše norma
* pro jistotu se doporučuje vložit i meta hlavičku pro přesměrování po zadaném počtu uplynutých sekund - <meta http-equiv="refresh" content="1;URL=http://url.to/go" />
* za voláním header("Location: ...") se doporučuje ukončit zpracování skriptu (tj. "exit;" popřípadě ještě před ním header("Connection: close"); ) aby výstup dál nepokračoval.
* pokud to používáš na více než jednom místě, napiš si na to funkci (metodu)
snad ti to pomůže ;-)
maks
Profil
divadlo kokoko:
Tvůj skript jsem nezkoumal,
to je možná ta chyba - nepotřebuji neurčité "rady", vím, jak se s headerem pracuje. Bohužel, ač ti asi trvalo poměrně dlouho sepsat sbírku pravidel pro header, znám je.

Nicméně to neřeší nic na tom, že „Zajímavé je, že pokud tuto adresu zadám i ve FF poprvé, přesměrování se provede. Při druhém pokusu FF něco načítá (a nenačte do konce).
AM_
Profil
maks:
Při druhém pokusu FF něco načítá (a nenačte do konce)
to zavání nějakým zacyklením. Zkus si pohrát s tím, jestli skript k místu s header dojde (třeba před něj dej die("došel")), v lepším případě nasaď nějaké prostředí, které umí PHP debuggovat - tak najdeš velice rychle, kde je problém.
maks
Profil
AM:
o zavání nějakým zacyklením.
to mě taky napadlo, ale v Chrome to funguje dobře a...

... ve FF napoprvé taky, jen při druhém pokusu skončím špatně. Dám-li si místo header nějaké třeba echo/die, vždy se vypíše. Dám-li die() za header, nedostanu se k němu - přesměrování se podruhé neprovede.
AM_
Profil
if (!isset($_SESSION['loged']) and substr($_SERVER['REQUEST_URI'], -6) != "login/")
je to možná blbost, ale poslední, která mě napadá: nemůže se stát, že třeba v REQUEST_URI je u firefoxu jen admin/login a ne admin/login/ ?
Tohle by to vysvětlovalo, cyklické přesměrování. Možná vzniká i v jiném kousku kódu, než v tomhle, nevím.
maks
Profil
AM:
nee, lomítko tam je.

Mám to na localhostu, zkusím to někam nahrát včetně zdroje, opravdu je to nějaké divné.

Nahraju zítra, pošlu odkaz i na problémové PHP soubory.
Cup
Profil
nezkoumal jsem ... ale možná jsem měl stejný problém, nevím co to bylo ale vyřešil jsem to tímto

 header("location: " . $SERVER . "admin/index.php"); exit; 


v případě že se nepřesměruje, se to ukončí, ale když sem to tam dal a dostalo se to do té větve tak je to stejně jedno. A nevím proč a jak ale pomohlo to a přesměrování normálně funguje, bez exit ne ... s exit ano ... není to u všech přesměrováních ... ale někde mi to bez toho prostě nejde. Když problém vyřešíš budu rád když to sem napíšeš.
maks
Profil
Cup:
ale možná jsem měl stejný problém, nevím co to bylo ale vyřešil jsem to tímto
exit tam mám, jen jsem jej nenapsal sem. Samozřejmě mě i tohle napadlo - k tomu exitu se to nedostane, protože přesměrování začne a... pokračuje do aleluja.
AM_
Profil
maks:
k tomu exitu se to nedostane, protože přesměrování začne a... pokračuje do aleluja.
kód se k němu téměř jistě dostane, jen už to nevidíš v prohlížeči (ten je přesměrován jinam, tak už nezjistí, zda se vykonávání PHP přeruší).
Jsem si téměř jist, že tam bude nějaká logická chyba, která vede k cyklickému přesměrování. Zkus se přesměrovávat třeba na admin/test_redir, a uvidíš, jestli to k tomu dojde nebo ne. Nebo lépe, třeba na admin/login/?redir=1, a hned na začátku skriptu ověřit, zda existuje ?redir=1, pokud ano, tak nepřesměrovávat dál a nějak se o tom informovat.

Osobně si myslím, že podmínka
substr($_SERVER['REQUEST_URI'], -6) != "login/")
je trochu hrůzostrašná; soudím z ní, že používáš mod_rewrite, tak bych na parsování adresy použil nějaký inteligentnější algoritmus, např. si ji rozdělit přes explode a ověřovat na jaké jsem stránce nějak inteligentně; tohle je strašně chatrné, představ si, copak se stane, pokud bys jednou měl na webu tyto adresy a nebyl přihlášen:
/admin/login/?error=bad_password
/foo/bar/login/
maks
Profil
AM:
Osobně si myslím, že podmínka je trochu hrůzostrašná
bude tam ověření proměnné z GET.

Asi to nechám plavat, na hostingu to běží. Localhost je mi trochu záhadou, ale co :-)


Děkuji všem za účast.

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

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