Currently Browsing: Solutions

Hashowanie haseł z solą

Przeglądając forum.php.pl często widziałem, jak użytkownicy przechowują hasła w swoich bazach danych. Najczęściej używają funkcji hashujących md5, sha1 i sha2. Wszystko wygląda bardzo dobrze, hasła są przechowywanie bezpiecznie. No właśnie… na ile bezpiecznie.

Nie będę tutaj rozwodził się nad zabezpieczeniem baz danych, w których owa baza haseł się znajduje, ale nad samym zahashowanym ciągu. Wszyscy doskonale wiemy, że istnieją bazy md5 (sha1, sha2 również).

Przezorny zawsze ubezpieczony. Wiadomo, że nigdy nic nie wiadomo.

Pokażę, jak dodatkowo zabezpieczyć nasze hasła. Będą przechowywane w tej samej bazie danych, używając tych samych metod hashowania, a jednak szansa na “złamanie” hasła (wyszukania w bazie) będzie niemożliwa. Posłużymy się ciągiem znaków zwanym przez programistów solą (salt). Przykład implementacji możemy znaleźć w forum IPB, natomiast phpBB pozbawione jest tego fjuczuru ficzera. Cała sprawa sprowadza się do wygenerowania dowolnego kawałka ciągu znaków i doklejenia go do hasła. Sól potrzebna nam będzie również przy porównaniu hasła, więc trzeba ją zapisać w bazie danych obok hasła.

Poniżej zamieszczam przykładową klasę, która obsługuje solenie haseł. Doklejanie soli może być napisane w dowolny sposób, zależy to od Waszej wyobraźni. Ja dodatkowo dodałem element “losowy” w postaci doklejenia do soli wyniku działania funkcji microtime().

WordPress sitemap plugin

Na potrzeby pewnego projektu o pewnej nazwie, o której niebawem się przekonacie, powstał nowy plugin. Generuje on sitemapa przyjaznego dla Google. Po co to wszystko… Rejestrując się w google mamy możliwość skorzystać z wielu narzędzi webmastera. Jednym z nich jest “pomaganie” robotowi w indeksowaniu naszej strony, poprzez podanie mu sitemapu po którym powinien się poruszać. Po zweryfikowaniu naszej strony w systemie google, proszeni jesteśmy o podanie sitemapu (więcej o weryfikacji).

W tym miejscu z pomocą przychodzi nam WordPress ContexlinkSitemap Plugin. Plugin przede wszystkim:

  • tworzy mapę witryny uwzględniając wszystkie notki i podstrony na blogu oznaczone jako “published”,
  • uwzględnia strukturę permalinków, URL’i przyjaznych dla wyszukiwarek sprecyzowanych w konfiguracji bloga
  • datę ostatnich zmian na stronie głównej oraz w każdym linku z osobna
  • dostosowany do mapy google:
    https://www.google.com/webmasters/tools/docs/pl/protocol.html
  • jest bezpłatny : -)

Instalacja pluginu:

  1. Pobierz paczkę pluginu stąd (format ZIP)
  2. Folder ContextlinkSitemap skopiuj do folderu wp-content/plugins/
  3. Plik sitemap.xml skopiuj do folderu głównego bloga i nadaj mu chmod 777
  4. Aktywuj plugin w zakładce Plugins wpanelu administracyjnym bloga

Dodanie mapy witryny do google:

  1. Zaloguj się na google.com na swoje Google Account lub Gmail Account.
  2. W nagłówku strony głównej google.com przejdź w sekcję “Moje konto”
  3. Z listy “Moje usługi” wybierz pozycję “Narzędzia dla webmasterów”
  4. Dodaj swoją stronę.
  5. Wybierz formę weryfikacji strony i postępuj ze wskazówkami google
  6. Gdy strona pojawi się w tabeli oraz jej status zostanie oznaczony jako “zweryfikowana”, kliknij w opcję “Dodaj mapę” i podaj adres URL mapy strony (defaultowo http://twojblog.pl/sitemap.xml, czyli tam, gdzie wrzuciłeś plik).

Dodatkowa konfiguracja:

W celu szczegółowej konfiguracji pluginu, możesz:

  • zmienić ścieżkę mapy w stałej CONTEXLINK_MAP_FILE
  • zmienić częstotliwość automatycznej aktualizacji mapy w stałej CONTEXLINK_MAP_UPDATE, wartość podawana w sekundach, defaultowo co 2 dni: 3600 * 24 * 2.
  • zmienić miejsce wykonywania aktualizacji, zwykle jest to przy ładowaniu sekcji head na blogu. Aby dokonać zmian, należy zmienić miejsce akcji: add_action(‘wp_head’, ‘ContexlinkSitemapAutogenerate’); Pełną listę miejsc, w których można wykonać operację możesz znaleźć tutaj: http://codex.wordpress.org/Plugin_API/Action_Reference

Autoload – praktyczne mapowanie

O autoloadzie klas było już głośno, rozpatrywaliśmy wszelkie za i przeciw w wielu miejscach choćby tu, tu i tu.

Mechanizm automatycznego ładowania potrzebnych nam klas jest bardzo dobrym sposobem na zrelaksowanie się poprzez brak przymusu ręcznego ładowania plików potrzebnych do działania aplikacji. Znajdźmy receptę na owe pytanie przedstawiając dwa najpopularniejsze sposoby trzymania klas w np. frameworkach.

  • Zend Framework i Rapide mają dość sztywną, lecz nie wymagającą specjalnego kombinowania technikę umieszczania plików w core. Sposób nazewnictwa jest bardzo prosty: Folder_Subfolder_Klasa – owy zapis odnosi się do ./Folder/Subfolder/Klasa.Class.php.

  • W moim frameworku Vframe zastosowałem technikę, w której pliki leżą sobie „wolność w core, nazewnictwo klas nie tyczy się ich ścieżki, np. NazwaKlasy może odnieść się do ./NazwaKlasy.Class.php lub ./Folder/Subfolder/ NazwaKlasy.Class.php.

Spróbuję opisać drugi – mój – sposób na ładowanie plików z core aplikacji. Potrzebna nam będzie klasa, która jest w stanie przeskanować całe core i zapisać je do tablicy. Aby było łatwiej, skan zostanie zaserializowany do pliku jako mapa folderu. Co jeżeli plik nie będzie istniał w core? Wówczas mapa zostanie stworzona od nowa, jeżeli to nie pomoże – wyrzucimy wyjątek.

Projektujemy naszą klasę, nazwiemy ją przykładowo Autoload, metody:

  • Load($sLibrary, $bRemapped = false) – metoda która będzie odpowiedzialna za załadowanie pliku oraz (jeżeli nie będzie istniała) stworzenie tablicy plików. W wypadku braku pliku zostanie ponownione wywołanie metody tworzenia mapy plików z przymusowym przeskanowaniem folderu klas oraz tym samym odpalenie metody samej siebie z przyjęciem drugiego jej parametru na true – brak ponownego skanowania folderu i wyrzut wyjątku.

  • Map($bUseTemp = true) – metoda odpowiedzialna za stworzenie tablicy z plikami na podstawie pliku mapy poprzez odserializowanie danych w nim zapisanych. Jeżeli parametr otrzyma wartość false lub plik mapy nie będzie możliwy do odczytu, wówczas tworzona zostanie mapa, zapisana do pliku mapy oraz do tablicy klasy.

  • FormatName($sLibrary) – metoda formatująca nazwę klasy: Klasa.Class.php

Wykorzystamy trzy stałe:

  • const _LibDir – określa ścieżkę folderu z klasami

  • const _LibSurfix – surfixy plików (.Class.php)

  • const _LibMap – ścieżka i nazwa pliku mapy

Potrzebna będzie nam jeden statyczny, prywatny parametr klasy, który jest sam w sobie jej singletonem, więc każda instancja klasy będzie z niego korzystała:

private static $_aCoreMap = array();

Ok, teraz wystarczy użyć funkcji __autoload() i wykorzystać naszą klasę:

[php]function __autoload($sLibrary)
{
try
{
Autoload::Load($sLibrary);
}
catch(AutoloadException $oException)
{
// some message to display
die(‘Autoload failed: ‘ . $oException->getMessage());
}
}[/php]

Tworzymy osobisty wyjątek dla autoloadera:

[php]class AutoloadException extends Exception
{

}[/php]

oraz samą klasę:

[php] class Autoload
{
const _LibDir = ‘Core/’;
const _LibSurfix = ‘.Class.php’;
const _LibMap = ‘Map.tmp’;

private static $_aCoreMap = array();

public static function Load($sLibrary, $bRemapped = false)
{
if(!count(self::$_aCoreMap))
self::Map();

$sLibraryFile = self::FormatName($sLibrary);

if(!isset(self::$_aCoreMap[$sLibraryFile]))
{
if($bRemapped)
// if we remapped core and library dosen’t exists – throw an exception
throw new AutoloadException(‘Library “‘ . $sLibrary . ‘” has not been found in directory map!’);
else
{
// ok, let’s go map core again without using map from file
self::Map(false);
// try load class from core directory again…
self::Load($sLibrary, true);
}
}

require_once(self::$_aCoreMap[$sLibraryFile]);
}

public static function Map($bUseTemp = true)
{
// if map is ok and we counld use it, get the map from file…
if($bUseTemp && is_readable(self::_LibMap))
self::$_aCoreMap = unserialize(file_get_contents(self::_LibMap));
// …unless we have to scan core and make map
else
{
// clear array and remamp directory
self::$_aCoreMap = array();

foreach(new RecursiveIteratorIterator(new RecursiveDirectoryIterator(self::_LibDir)) as $oFile)
{
$sFile = $oFile->getFilename();

if(isset(self::$_aCoreMap[$sFile]))
throw new AutoloadException(‘Core duplication “‘.$sFile.’” found!’);
else
self::$_aCoreMap[$sFile] = $oFile->getPathname();
}

// ok, save map to file
if(!file_put_contents(self::_LibMap, serialize(self::$_aCoreMap)))
throw new VframeException(‘Cannot create core map!’);
}
}

private static function FormatName($sLibrary)
{
return $sLibrary . self::_LibSurfix;
}
}
?>[/php]

Całą paczkę klasy i zastosowań możecie pobrać tutaj.

Next Entries »