Přejít k navigační liště

Zdroják » PHP » Implementace přihlašování pomocí OpenID

Implementace přihlašování pomocí OpenID

Články PHP, Různé

Je implementace OpenID těžká? Na praktickém příkladu si ukážeme, že přihlašování pomocí OpenID lze implementovat snadno. Nebudeme zabíhat do podrobností ani probírat implementační detaily; pouze ukážeme, že v té nejjednodušší podobě je mezi webem a webem s podporou OpenID rozdíl pouhých několika desítek minut.

Jedna z častých výhrad proti OpenID zní: „Já bych to třeba i nasadil, ale nechce se mi studovat hory manuálů a psát nějakou implementaci nějakého protokolu.“ U většiny protokolů nic takového dělat nemusíte, pokud vysloveně nechcete, namísto toho můžete použít hotové knihovny. U OpenID je tomu nejinak.

V následujícím textu odbočíme od šedivé teorie, kterou jsme se zabývali v předchozích dílech našeho seriálu o moderních autentizačních metodách, a ukážeme si jednoduchý příklad té nejrychlejší implementace OpenID přihlašování se standardní knihovnou od JanRain ze stránek OpenID Enabled.

Tradiční přihlášení

Představme si, že máme nějaký web, kam se mohou uživatelé registrovat a přihlašovat – diskusní fórum, blog, galerii fotografií, cokoli… Tradiční přihlášení bude vypadat třeba nějak takhle (login.php):

<?php
if (isset($_POST['login'])) {
  $jmeno = $_POST['jmeno'];
  $heslo = $_POST['heslo'];

  /**
   * Následuje ověření jména a hesla, např. proti databázi. Zde pro jednoduchost
   * zůstaneme u volání (blíže nedefinované) funkce "overeni()"
   */
  $spravne = overeni ($jmeno, $heslo);
  if ($spravne) {
    /**
     * Nějaké akce spojené se správným přihlášením - vytvoření session apod. Zde jen vypíšeme hlášení
     */
     print 'Prihlaseni v poradku, prihlasen jako '.$jmeno;
     die();
  } else {
     print 'Chyba';
     die();
  }
}

//dummy funkce overeni() pro testování - schválí kombinaci admin/nimda
function overeni($jmeno, $heslo) { return ($jmeno=='admin' && $heslo=='nimda'); }

?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="cs" xml:lang="cs">
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Přihlášení</title>
  </head>
  <body>
  <form method="post" action="login.php">
  <fieldset><legend>Přihlášení jménem a heslem</legend>
  <p>
    <label for="jmeno">Jméno</label>
    <input type="text" id="jmeno" name="jmeno" />
  </p>
  <p>
    <label for="heslo">Heslo</label>
    <input type="password" id="heslo" name="heslo" />
  </p>
  <p><input type="submit" name="login" value="Přihlásit" /></p>
  </fieldset>

  </form>
  </body>
</html> 

Příklad je opravdu velmi zjednodušen, nijak v něm nejsou rozebírány detaily implementace – např. zapamatování přihlášeného uživatele přes session, nejsou řešené chybové stavy (jen vypisuje lakonické „chyba“), nejsou v něm ošetřené vstupy apod., protože to vše není v tuto chvíli podstatné. V praxi by nejspíš byl taky oddělen formulář od PHP skriptu. Pro tuto chvíli však stačí tenhle příklad, z něho vyjdeme.

Poznámka: Příklady z tohoto článku jsou umístěny na adrese http://misc.ma­ly.cz/openid/. Můžete si tedy rovnou zkoušet jejich chování „live“. Tento primitivní přihlašovací skript tedy najdete na adrese http://misc.ma­ly.cz/openid/lo­gin.php.

Připravujeme se na implementaci

Protože chceme implementovat přihlašování přes OpenID bez toho, abychom leželi mnoho dní v dokumentaci a pak týden psali a ladili vlastní implementaci, sáhneme po hotové OpenID knihovně. V době psaní článku je aktuální PHP verze 2.1.2 (dokumentace).

Stáhneme si ji (.zip – .tar.bz2) a rozbalíme. V archivu nalezneme kromě vlastní implementace OpenID (adresář Auth) i testovací skripty, dokumentaci, příklady a další soubory, kterými se v tuto chvíli nemusíme zabývat.

Požadavky knihovny

JanRain OpenID ke svému běhu potřebuje některé knihovny, jako jsou bcmath/gmp, cURL či podpora XML. Naštěstí je většina těchto knihoven standardně dostupná na většině instalací PHP, a pokud nejsou, tak je dokáže OpenID implementace obejít. To, jestli je vaše instalace vhodná či zda nastanou nějaké problémy, si můžete ověřit snadno: Nakopírujte soubor „detect.php“ z adresáře examples na váš server a spusťte ho. Skript otestuje prostředí a vypíše informace o tom, zda je vyhovující. (Ukázka – server plně dostačuje, doporučuje se instalace gmp pro zrychlení matematických operací.)

Nejčastějším problémem, se kterým jsem se setkal, byla neexistence zdroje náhodných čísel ve Windows. Naštěstí s tím knihovna počítá a nabízí řešení, spočívající v zapsání direktivy define('Auth_OpenID_RAND_SOURCE', null); před voláním OpenID knihoven.

Příprava prostředí

OpenID knihovna potřebuje prostor, kam si bude ukládat potřebné informace, např. komunikační klíče pro jednotlivé servery nebo informace o uživatelích. Máme na výběr z několika možností – buď databáze (MySQL, SQLite, pgSQL) nebo soubor na disku. My zůstaneme v našem příkladu u té jednodušší možnosti, tedy u souborů v adresáři na disku. Budeme k tomu potřebovat pouze adresář na serveru, do něhož bude smět skript zapisovat (adresář nesmí být zvenčí viditelný, takže jej buď umístěte mimo strom dokumentů, nebo alespoň zakažte přístup přes .htaccess).

Na serveru si vytvoříme adresář „cache“ a nastavíme mu patřičná práva pro zápis. Pokud bude viditelný zvenčí, umístíme do něj soubor .htaccess, který obsahuje obligátní:

order deny,allow
deny from all 

Na server zkopírujeme rovněž celý adresář Auth.

Test funkčnosti

V tuto chvíli můžeme takříkajíc „zkusit štěstí“, nahrát na server i adresář examples a zkusit si zavolat skript /examples/con­sumer/index.php. Pokud vám výše zmíněný test pomocí „detect.php“ neukázal žádné chyby, máte velkou pravděpodobnost, že se vám ukáže testovací formulář:

PHP OpenId Authentication Example

Pokud se neukázal, tak příčiny bývají nejčastěji tyto:

  • Chybně nastavená práva k adresáři examples/consu­mer/_php_consu­mer_test
  • Spuštění na Windows bez direktivy Auth_OpenID_RAN­D_SOURCE (nutno přidat do examples/consu­mer/common.php)
  • Špatně rozbalený adresář Auth (např. změněno při přenosu na „auth“)

Pokud není příčinou nic z nich, je třeba trochu hledat – naštěstí jsou ladicí výstupy celkem srozumitelné a člověka navedou.

Pokud se testovací formulář ukáže, zkuste si zadat své OpenID a nechat své přihlášení ověřit. Ověření by mělo proběhnout bez problémů. Problém se může vyskytnout, pokud používáte Firefox, máte nainstalované rozšíření NoScript a zapnutou CSRF ochranu – v takovém případě můžete u některých OpenID providerů dostat chybu Bad signature, i když je přihlášení v pořádku. Příčinou je drobná chyba v ukázkovém příkladu.

Implementujeme OpenID

Knihovnu máme na serveru v adresáři Auth, ověřili jsme si, že funguje, takže můžeme přistoupit k vlastní implementaci. Nejprve přidáme do naší přihlašovací stránky další formulář pro přihlášení přes OpenID. Tentokrát si vystačíme s jediným textovým polem a přesměrujeme zpracování na jiný skript (jen kvůli přehlednosti, požadavek by mohl klidně zpracovávat stejný skript):

<!-- OpenID formulář -->
<form method="post" action="login2-openid.php">
<fieldset><legend>Přihlášení přes OpenID</legend>
<p>
  <label for="openid">OpenID</label>
  <input type="text" id="openid" name="openid" />
</p>
<p><input type="submit" name="login" value="Přihlásit" /></p>
</fieldset>
</form> 

Pokud nepotřebujeme od uživatelů nic víc než jejich uživatelské jméno (kvůli identifikaci) a (třeba) e-mail a jméno, které se jim má zobrazit, tak se obejdeme zcela bez registračního skriptu. O tyto údaje totiž můžeme požádat přímo OpenID providera a dostaneme je při úspěšném přihlášení. Můžeme pak vytvořit registraci „na pozadí“ (pokud ji z nějakého důvodu potřebujeme, např. když chceme, aby každý uživatel měl záznam v databázi a svoje ID), nebo ji nemusíme zakládat vůbec.

OpenId formulář

Discovery a přesměrování na providera

Dalším krokem je vytvoření skriptu, který provede požadované akce a přesměruje uživatele na stránky jeho poskytovatele OpenID (viz minulý článek o mechanismu autentizace, kroky 2–4). OpenID knihovna naštěstí většinu operací dělá za nás, takže skript login2-openid.php může být opravdu jednoduchý (čísla kroků pochází z popisu v minulém díle):

<?php
//Odkomentujte následující řádek, pokud má skript běžet na Windows
//define('Auth_OpenID_RAND_SOURCE', null);

require_once "./Auth/OpenID/Consumer.php";
require_once "./Auth/OpenID/FileStore.php";
require_once "./Auth/OpenID/SReg.php";

session_start();

$trust_root = 'http://misc.maly.cz/openid/';
$return_to = $trust_root . 'login2-openid-finish.php';

    //Cesta k úložišti
    $store_path = "./cache";
    $store = new Auth_OpenID_FileStore($store_path);
    $consumer = new Auth_OpenID_Consumer($store);

    $openid = $_POST['openid'];

    // Kroky 2 - Discovery a 3 (na pozadí)
    $auth_request = $consumer->begin($openid);

    if (!$auth_request) {
        die("Neni platne OpenID");
    }

    /**
     * Požádáme o údaje ze SimpleRegister
     * Povinně budeme požadovat přezdívku,
     * volitelně pak skutečné jméno a e-mail
     */
    $sreg_request = Auth_OpenID_SRegRequest::build(
                    array('nickname'),
                    array('fullname', 'email'));

    if ($sreg_request) {
        $auth_request->addExtension($sreg_request);
    }

    // Krok 4 - přesměrování na server OpenID poskytovatele
    if ($auth_request->shouldSendRedirect()) {
      //Krátký požadavek a požadavky OpenID 1 jsou přesměrovány přes HTTP redirekt
        $redirect_url = $auth_request->redirectURL($trust_root, $return_to);
        if (Auth_OpenID::isFailure($redirect_url)) {
            print("Chyba pri presmerovani: " . $redirect_url->message);
            die();
        } else {
            header("Location: ".$redirect_url);
            die();
        }
    } else {
        // Dlouhé OpenID 2 požadavky - vygenerujeme formulář a JavaScript jej odešle jako POST
        $form_id = 'openid_message';
        $form_html = $auth_request->htmlMarkup($trust_root, $return_to, false, array('id' => $form_id));

        if (Auth_OpenID::isFailure($form_html)) {
            print("Chyba pri presmerovani: " . $redirect_url->message);
            die();
        } else {
            print $form_html;
        }
    }
?> 

Ve skriptu jsou nejprve načteny potřebné soubory, tedy OpenID klient (consumer), FileStore (třída pro ukládání pracovních souborů na disk) a SReg (třída pro práci s rozšířením Simple Registration). Následuje nastavení dvou důležitých údajů, a to jednak adresy, pro niž je povolení požadováno (typicky URL serveru nebo jeho podčásti – v našem případě to je http://misc.ma­ly.cz/openid/), jednak návratové adresy (u nás to bude login2-openid-finish.php). Po nezbytných inicializacích úložiště a klienta je spuštěn proces dle kroků 2 a 3, a to voláním $consumer->begin($openid);

Výsledkem volání této funkce je objekt typu AuthRequest – samosebou pokud bylo volání úspěšné a OpenID identifikátor prošel zjišťovacím procesem (discovery). Tento objekt má metody, jimiž můžeme přidat požadavky na rozšíření (použili jsme rozšíření Simple Registration, budeme požadovat přezdívku a volitelně e-mail a plné jméno). Pak už jen přesměrujeme uživatele na stránky poskytovatele – OpenID 2 zavedl možnost přesměrování dlouhých požadavků jako POST, a i na to knihovna myslí, my se musíme jen správně rozhodnout, zda použít HTTP nebo zda odeslat formulář JavaScriptem.

Přihlašování přes MyOpenID

Opět pro jednoduchost nejsou ve skriptu ošetřeny chybové stavy, chyba je pouze vypsána a skript zastaven. Ošetření těchto stavů je u slušné aplikace samosebou nutné, ale zde je mimo záběr tohoto článku.

Návratový skript

Návratový skript (login2-openid-finish.php) je místo, kam se uživatel vrátí od OpenID providera. V tomto skriptu zbývá jen ověřit, zda celý proces dopadl dobře (opět jedním voláním jedné metody objektu Consumer) a podle výsledku s uživatelem naložit.

<?php
//Odkomentujte následující řádek, pokud má skript běžet na Windows
//define('Auth_OpenID_RAND_SOURCE', null);

require_once "./Auth/OpenID/Consumer.php";
require_once "./Auth/OpenID/FileStore.php";
require_once "./Auth/OpenID/SReg.php";

session_start();

$trust_root = 'http://misc.maly.cz/openid/';
$return_to = $trust_root . 'login2-openid-finish.php';

//Cesta k úložišti
$store_path = "./cache";
$store = new Auth_OpenID_FileStore($store_path);
$consumer = new Auth_OpenID_Consumer($store);

// Dokončení - krok 7
$response = $consumer->complete($return_to);

//Ověříme výsledek z $response->status
if ($response->status == Auth_OpenID_CANCEL) {
    $msg = 'Autentizace zrusena.';
} else if ($response->status == Auth_OpenID_FAILURE) {
    $msg = "Autentizace selhala: " . $response->message;
} else if ($response->status == Auth_OpenID_SUCCESS) {
    // Autentizace v poradku
    $openid = $response->getDisplayIdentifier();
    $esc_identity = htmlspecialchars($openid);

    $success = sprintf('V poradku overen jako ' .
                       '<a href="%s">%s</a>.',
                       $esc_identity, $esc_identity);

    if ($response->endpoint->canonicalID) {
        $escaped_canonicalID = htmlspecialchars($response->endpoint->canonicalID);
        $success .= '  (XRI CanonicalID: '.$escaped_canonicalID.') ';
    }

    //Získání informací z rozšíření Simple Registration
    $sreg_resp = Auth_OpenID_SRegResponse::fromSuccessResponse($response);
    $sreg = $sreg_resp->contents();
    if (@$sreg['email']) {
        $success .= "  Mail: '".htmlspecialchars($sreg['email']) . "'";
    }
    if (@$sreg['nickname']) {
        $success .= "  Prezdivka: '".htmlspecialchars($sreg['nickname']) . "'";
    }
    if (@$sreg['fullname']) {
        $success .= "  Jmeno: '".htmlspecialchars($sreg['fullname']) . "'";
    }
  //Přihlášení úspěšné... vypíšeme hlášku a přesměrujeme uživatele do
  //zabezpečené oblasti
  print($success);
  die();
}
//Přihlášení selhalo.
print($msg);die();
?> 

Skript začíná stejně jako předchozí – načtením potřebných souborů a inicializací objektu Consumer. Následuje volání $consumer->complete($re­turn_to), které zajistí všechny potřebné operace – převezme parametry, ověří podpis a vyhodnotí celý proces. Výsledkem je objekt Response, který ve své vlastnosti status obsahuje informaci o tom, zda byla autentizace úspěšná. Pokud ano, můžeme si z tohoto objektu převzít i informace, předané rozšířením Simple Registration, a ty si uložit pro další potřebu.

V tomto bodu máme tedy k dispozici informace o přihlášeném uživateli, máme jeho „uživatelské jméno“ (= OpenID identita) a máme další informace, potřebné např. pro vytvoření uživatelského účtu. Další postup, jako např. vytvoření session, uložení informací či pohyb po webu, je do značné míry podobný oné „klasické“ metodě (OpenID identifikátor místo jména apod.) a nespadá už do tématu tohoto článku.

Nový přihlašovací skript s podporou OpenID si můžete rovněž vyzkoušet na adrese http://misc.ma­ly.cz/openid/lo­gin2.php.

Zdrojové kódy použité v tomto článku si můžete stáhnout: OpenID demo (ZIP 4554 bytů).

Závěr

Ukázali jsme si nejjednodušší a nejrychlejší způsob implementace OpenID přihlašování na web. Článek prosím neberte jako hotové instantní řešení ani jako všeobsahující tutoriál, který vám pomůže s každým aspektem implementace OpenID. Berte ho spíš jako studijní materiál, jako základ či naprosté minimum, od něhož se můžete odpíchnout. Sami vidíte, že implementace přihlášení pomocí OpenID není nijak složitá ani mysteriózní.

Téměř povinný disclaimer: Pro OpenID platí stejná bezpečnostní pravidla jako pro jakoukoli jinou technologii: Vybírejte si důvěryhodné poskytovatele, co můžete, to si ověřte více způsoby, a když použijete cizí knihovnu, tak ji pravidelně aktualizujte! Pokud považujete cizí knihovnu v systému za výraznou bezpečnostní díru a chystáte se rovnou celé OpenID zatratit, tak ještě předtím uvažte, že OpenID je otevřená technologie se solidní dokumentací, takže si samosebou můžete napsat vlastní implementaci OpenID klienta.

Implementovali jste už někdy OpenID?

Komentáře

Subscribe
Upozornit na
guest
24 Komentářů
Nejstarší
Nejnovější Most Voted
Inline Feedbacks
View all comments
danaketh

Super. Tohle je přesně to co jsem potřeboval. Spouštím Kate a jde se na věc.

Kuka

Velice zajímavý článek, o OpenID jsem zaslechl, vypadá to zajimavě, jen mě napadá, jak je to s "kompatibilitou"? Zkusil jsem si vytvořit účet na openid.cz ale script mě nepřihlásí (Neni platne OpenID). Je to tak, že knihovna spolpracuje jen s určitým serverem? Je to tak, že na openid.cz budu mít svou přezdívku, ale na openid.com ji bude mít někdo jiný? (jen pro příklad)

Kuka

Uf tak to díky za velice dobrou informaci, to je dobré vědět

pan_tau

Vite nekdo jak vypada google openId, mam ucet na gmailu, ale nenasel jsem, jak vypada moje openId. Do ukazkovych formularu funguje:

https://www.google.com/accounts/o8/id

Jenze tohle nevypada vubec jako id ani si to nikdy nemuzu zapamatovat. Mate s tim nekdo zkusenosti?

PS: a co openId pan_tau.root.cz?

Christof

Když se pošle pár extra parametrů, tak se z Googlu dá vyrazit e-mail uživatele, takže zas tak anonymní není.

pan_tau

Vyresil problem 'zapamatovani si adresy' delegaci v me webove strance pridanim nasledujiciho kodu:

<link rel="openid2.provider" href="https://www.google.com/account /o8/ud">                                                                                 
<link rel="openid2.local_id" href="https://www.google.com/accounts/o8/id">

Na prikladu v clanku pak funguje zadani pan_tau.matfyz.cz. Funguje to jen s openId 2.0, bohuzel s pomoci openid.server a openid.delegate se mi delegaci nepodarilo nastavit.

To reseni Googlu nakonec neni tak spatne, nebot je anonymni a navic pomoci delegace si kazdy muze nastavit sve vlastni id.

Andrew

OpenID od Google je dost zapeklité a pokud jste se těšili, že když máte na Google účet, tak že máte i OpenID, tak vás zklamu.
Google opravdu používá protokol OpenID ve druhé verzi, ale nejprve se je potřeba připojit na jeho server. A jelikož uživatelským jménem do Googlu není jen gmail, ale libovolný mail, který jste zadali při registraci, nemohl udělat to, co seznam, tj. vygenerovat z vašeho mailu id (neco.id.seznam.cz). OpenID totiž zároveň slouží jako url, kde se ověřuje, tj. url správce vašeho OpenID.
Z těchto důvodů je tedy potřeba, aby stránka "Googlí" přihlašování podporovala, tj. vy jste někde vybrali, že to, co zadáváte, není běžný OpenID, ale účet Google. Pak už stránka ví, kam se připojit a další komunikace probíhá dle standardu.

Andrew

Souhlasím, ale s malou výhradou. Zadat tu adresu opravdu lze bez problému a pak vše funguje. Pochybuji ovšem, že by si ji ale některý uživatel google pamatoval a chtěl ji používat. Předpokládal jsem navíc, že dotaz směřoval spíš na použití uživatelského jména, kterým se přihlašuje do Google, tedy např. neco@gmail.com, cokoliv@ledacos.cz apod. Proto jsem také uváděl jako příklad Seznam.cz, který to vyřešil hezky. Pokud ale opravdu stránka umožní vybrat, že se přihlašuji přes Google (ale taky např. Yahoo atd.), uživatel opravdu může zadat to neco@gmail.com. Někoho by mohlo pak napadnout, že chybí univerzálnost OpenId, ale ve skutečnosti implementace na web je velmi jednoduchá, neboť mohu používat vše stejně jako u OpenId a jen musím říct, kam se připojuji (dle toho výběru uživatele).

burlog

U seznamu muzete byt prihlasen take pod jinym emailem, pak vase openid(od seznamu) bude vypadat username.id.seznam.cz/domain.com

v6ak

Je IMHO blbost brát bezhlavě mail z těch doplňujících informací o OpenID, protože tím jej stejně neověříte. Jediná možnost je, že souhlasí do jisté míry doména. Ale jak? Jen tld a druhý řád většinou postačí, riziko by bylo asi jen u freehostingů s doménou třetího řádu. Tak nevím, stejně je to potřeba ověřit, jen můžu vynechat ptaní se uživatele, což taky může ocenit.

aprilchild

Podivejte se na RPXNow.com (https://rpxnow.com), za sluzbou stoji JanRain a jedna se o zdaleka nejjednodussi (implementacne) reseni autentikace k vasemu webu. Podporuje (krome LiveID – otazkou casu nez MS prejde na OpenID) prakticky vse. Pomoci mapovani (mapping API) ani nemusite menit db schema vasi aplikace.

Nemusi mozna vyhovovat vsem, ale i z uzivatelskeho hlediska je to komfortni (a jako bonus: "RPX can request profile and registration data from the user using the Simple Registration OpenID extension, the HCard microformat, and soon via the new Portable Contacts protocol." – tohle bude skvele!).

aprilchild

Souhlasim, pokud chce clovek mit kontrolu, integruje si to sam. Serverum rpx nezbyva nez verit :(. Mne trochu uklidnuje fakt, ze za tim stoji JanRain. Jenze ja uz nemam po x implementacich cas na integraci do dalsi aplikace, o moznych knihovnach typu Facebook, MySpace aj. ani nemluve. Alespon pred rokem a pul to sice nebylo extra obtizne, ale otravne urcite. Chci rovnez jednoduchou spravu a netrapit se aktualizaci knihoven, sledovanim bezpecnostnich zmen, … Rpx mi vyhovuje jako instantni reseni, vic za tim neni.

kluvi

Nechcete nahodou napsat nekdo nejakej kratsi clanecek o specialitkach ohledne OpenID u googlu? Konkretne me by treba zajimalo jak s tady pouzitou knihovnou ziskam emailovou adresu (tady v diskuzi se o tom nekdo zminil)

kluvi

Mno tak me neco napadlo… Jelikoz se ta googli openid identifikuje jako "kdosi kdo ma ucet u google" a ja bych potreboval aspon nejakej identifikator (mejl). Tak me napadlo, ze by bylo dobry, aby se tomu uzivatelovi zobrazila ta prihlasovaci stranka ovsem s predvyplnenym mejlem (kterej by zadal na mejch strankach). Da se to googlu nejak poslat v pozadavku?

Watchick

Zdravím, na http://uzivatele.damak.cz/openid/login2.php
mám tedy váš script, s dobře nainstalovanou knihovnou (přesně podle návodu, se správnými cestami ke scriptům…) zkuste zadat open ID, vyhodí to buďto error, ze ID neni nalezeno, nebo error:

Fatal error: Define Auth_OpenID_RAND_SOURCE as null to continue with an insecure random number generator. in /var/www/web2/damak.cz/uzivatele.damak.cz/openid/Auth/OpenID/CryptUtil.php on line 52

nevíte co s tím?

bum

Ahoj. Měl jsem problém u registrování z openid.org, protože identifikátor není unikátní a já se na to spoléhal. Identifikátor buď může být ve tvaru xxx.openid.org
nebo xxx.openid.org/xxx. Jen jsem chtěl na to upozornit ostatní php newbe jak sem já :)

haff

Enum a statická analýza kódu

Mám jednu univerzální radu pro začínající programátorty. V učení sice neexistují rychlé zkratky, ovšem tuhle radu můžete snadno začít používat a zrychlit tak tempo učení. Tou tajemnou ingrediencí je statická analýza kódu. Ukážeme si to na příkladu enum.

Pocta C64

Za prvopočátek své programátorské kariéry vděčím počítači Commodore 64. Tehdy jsem genialitu návrhu nemohl docenit. Dnes dokážu lehce nahlédnout pod pokličku. Chtěl bych se o to s vámi podělit a vzdát mu hold.