Den här guiden visar hur du kan lagra dina sessioner säkert i en mySQL -databas. Vi kommer också att kryptera all sessionsdata som går in i databasen, vilket innebär att om någon lyckas hacka in databasen är all sessionsdata krypterad med 256-bitars AES-kryptering.
Steg
Metod 1 av 3: Konfigurera mySQL -databas
Steg 1. Skapa en MySQL -databas
I den här guiden skapar vi en databas som heter "secure_sessions".
Se hur du skapar-en-databas-i-phpMyAdmin.
Eller så kan du använda SQL -koden nedan för att skapa en åt dig.
Skapa databaskod:
SKAPA DATABASE `secure_sessions`;
Obs: Vissa värdtjänster tillåter dig inte att skapa en databas via phpMyAdmin, Lär dig hur du gör det i cPanel.
Steg 2. Skapa en användare med endast SELECT, INSERT och DELETE privilegier
Det betyder att om det någonsin inträffade ett säkerhetsbrott i vårt manus kunde hackaren inte släppa tabeller från vår databas. Om du verkligen är paranoid, skapa en annan användare för varje funktion.
-
Användare:
"sec_user"
-
Lösenord:
"eKcGZr59zAa2BEWU"
Skapa användarkod:
SKAPA ANVÄNDARE 'sec_user'@'localhost' IDENTIFIERAD MED 'eKcGZr59zAa2BEWU'; GRANT SELECT, INSERT, UPDATE, DELETE ON 'secure_sessions'.* TO 'sec_user'@'localhost';
Obs: Det är en bra idé att ändra lösenordet i koden ovan när du kör på din egen server. (Se till att du också ändrar din PHP -kod.) Kom ihåg att det inte behöver vara ett lösenord som du kan komma ihåg så gör det så komplicerat som möjligt. Här är en slumpmässig lösenordsgenerator.
Steg 3. Skapa en MySQL -tabell med namnet "sessioner"
Koden nedan skapar en tabell med 4 fält (id, set_time, data, session_key).
Skapa tabellen "sessioner":
SKAPA TABELL `sessioner` (` id` char (128) NOT NULL, `set_time` char (10) NOT NULL,` data` text NOT NULL, `session_key` char (128) NOT NULL, PRIMARY KEY (` id ')) MOTOR = InnoDB DEFAULT CHARSET = latin1;
Vi använder CHAR -datatypen för fält som vi känner till längden på, eftersom fälten "id" och "session_key" alltid kommer att vara 128 tecken långa. Att använda CHAR här sparar processorkraft.
Metod 2 av 3: Skapa filen session.class.php
Steg 1. Skapa klass
För att starta en ny klass måste du ange koden nedan:
Ny klass:
klass session {
Steg 2. Skapa _construct -funktion
Denna funktion kommer att kallas varje gång vi skapar en ny instans av ett objekt med hjälp av "session" -klassen. Du kan läsa om PHP _construct -funktionen här.
Den här funktionen ställer in vår anpassade sessionshanterare så att den är tillgänglig för användning så snart klassen är instanserad (dvs gjord/byggd/konstruerad).
_konstruktion funktion:
function _construct () {// ställ in våra anpassade sessionsfunktioner. session_set_save_handler (array ($ this, 'open'), array ($ this, 'close'), array ($ this, 'read'), array ($ this, 'write'), array ($ this, 'destroy'), array ($ this, 'gc')); // Denna rad förhindrar oväntade effekter när objekt används som sparhanterare. register_shutdown_function ('session_write_close'); }
Steg 3. Skapa start_session -funktion
Denna funktion kommer att kallas varje gång du vill starta en ny session, använd den istället för session_start ();. Se kommentarerna i koden för att se vad varje rad gör.
start_session -funktion:
function start_session ($ session_name, $ secure) {// Se till att sessionscookien inte är tillgänglig via javascript. $ httponly = true; // Hash -algoritm som ska användas för sessionen. (använd hash_algos () för att få en lista över tillgängliga hashningar.) $ session_hash = 'sha512'; // Kontrollera om hash är tillgängligt om (in_array ($ session_hash, hash_algos ())) {// Ställ in has -funktionen. ini_set ('session.hash_function', $ session_hash); } // Hur många bitar per hashtecken. // De möjliga värdena är '4' (0-9, a-f), '5' (0-9, a-v) och '6' (0-9, a-z, A-Z, "-", ","). ini_set ('session.hash_bits_per_character', 5); // Tvinga sessionen att endast använda cookies, inte URL -variabler. ini_set ('session.use_only_cookies', 1); // Hämta session cookie -parametrar $ cookieParams = session_get_cookie_params (); // Ställ in parametrarna session_set_cookie_params ($ cookieParams ["lifetime"], $ cookieParams ["path"], $ cookieParams ["domain"], $ secure, $ httponly); // Ändra sessionsnamnet sessionsnamn ($ sessionsnamn); // Nu startar vi sessionen session_start (); // Denna rad återskapar sessionen och tar bort den gamla. // Det genererar också en ny krypteringsnyckel i databasen. session_regenerate_id (true); }
Steg 4. Skapa öppen funktion
Denna funktion kommer att kallas av PHP -sessionerna när vi startar en ny session, vi använder den för att starta en ny databasanslutning.
öppen funktion:
funktion öppen () {$ host = 'localhost'; $ user = 'sec_user'; $ pass = 'eKcGZr59zAa2BEWU'; $ name = 'secure_sessions'; $ mysqli = ny mysqli ($ värd, $ användare, $ pass, $ namn); $ this-> db = $ mysqli; återvända sant; }
Steg 5. Skapa stängningsfunktion
Denna funktion kommer att kallas när sessionerna vill stängas.
stäng funktion:
funktion close () {$ this-> db-> close (); återvända sant; }
Steg 6. Skapa läsfunktion
Denna funktion kommer att anropas av PHP när vi försöker komma åt en session, till exempel när vi använder echo $ _SESSION ['något'];. Eftersom det kan finnas många samtal till den här funktionen på en enda sida, drar vi fördel av förberedda uttalanden, inte bara för säkerheten utan också för prestanda. Vi förbereder uttalandet bara en gång då kan vi köra det många gånger.
Vi dekrypterar också sessionsdata som är krypterade i databasen. Vi använder 256-bitars AES-kryptering i våra sessioner.
läsfunktion:
läs funktion ($ id) {if (! isset ($ this-> read_stmt)) {$ this-> read_stmt = $ this-> db-> förbered ("VÄLJ data FRÅN sessioner VAR ID =? LIMIT 1"); } $ this-> read_stmt-> bind_param ('s', $ id); $ this-> read_stmt-> execute (); $ this-> read_stmt-> store_result (); $ this-> read_stmt-> bind_result ($ data); $ this-> read_stmt-> fetch (); $ key = $ this-> getkey ($ id); $ data = $ this-> dekryptera ($ data, $ key); returnera $ data; }
Steg 7. Skapa skrivfunktion
Denna funktion används när vi tilldelar ett värde till en session, till exempel $ _SESSION ['something'] = 'något annat';. Funktionen krypterar all data som infogas i databasen.
skrivfunktion:
function write ($ id, $ data) {// Få unik nyckel $ key = $ this-> getkey ($ id); // Kryptera data $ data = $ this-> encrypt ($ data, $ key); $ time = time (); if (! isset ($ this-> w_stmt)) {$ this-> w_stmt = $ this-> db-> Prepar ("ERSTÄLL IN I sessioner (id, set_time, data, session_key) VÄRDEN (?,?,?,?) "); } $ this-> w_stmt-> bind_param ('siss', $ id, $ time, $ data, $ key); $ this-> w_stmt-> execute (); återvända sant; }
Steg 8. Skapa förstöringsfunktion
Denna funktion tar bort sessionen från databasen, den används av php när vi anropar funktioner som session_destroy ();.
förstör funktion:
function destroy ($ id) {if (! isset ($ this-> delete_stmt)) {$ this-> delete_stmt = $ this-> db-> prepar ("DELETE FROM sessions WHERE id =?"); } $ this-> delete_stmt-> bind_param ('s', $ id); $ this-> delete_stmt-> execute (); återvända sant; }
Steg 9. Skapa funktionen gc (sophämtare)
Den här funktionen är sopsamlarfunktionen som kallas för att radera gamla sessioner. Frekvensen i vilken denna funktion anropas bestäms av två konfigurationsdirektiv, session.gc_probability och session.gc_divisor.
gc () -funktion:
funktion gc ($ max) {if (! isset ($ this-> gc_stmt)) {$ this-> gc_stmt = $ this-> db-> förbered ("DELETE FROM sessions WHERE set_time <?"); } $ old = time () - $ max; $ this-> gc_stmt-> bind_param ('s', $ old); $ this-> gc_stmt-> execute (); återvända sant; }
Steg 10. Skapa getKey -funktion
Denna funktion används för att få den unika nyckeln för kryptering från sessionstabellen. Om det inte finns någon session returnerar den bara en ny slumpmässig nyckel för kryptering.
getkey () Funktion:
privat funktion getkey ($ id) {if (! isset ($ this-> key_stmt)) {$ this-> key_stmt = $ this-> db-> prepar ("SELECT session_key FROM sessions WHERE id =? LIMIT 1"); } $ this-> key_stmt-> bind_param ('s', $ id); $ this-> key_stmt-> execute (); $ this-> key_stmt-> store_result (); if ($ this-> key_stmt-> num_rows == 1) {$ this-> key_stmt-> bind_result ($ key); $ this-> key_stmt-> fetch (); return $ key; } annat {$ random_key = hash ('sha512', uniqid (mt_rand (1, mt_getrandmax ()), true)); returnera $ random_key; }}
Steg 11. Skapa krypterings- och dekrypteringsfunktioner
Dessa funktioner krypterar data från sessionerna, de använder en krypteringsnyckel från databasen som är olika för varje session. Vi använder inte den nyckeln direkt i krypteringen, men vi använder den för att göra nyckelhashen ännu mer slumpmässig.
kryptera () och dekryptera () funktioner:
privat funktionskryptering ($ data, $ key) {$ salt = 'cH! swe! retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39 = E@rAsp7c-Ph@pH'; $ key = substr (hash ('sha256', $ salt. $ key. $ salt), 0, 32); $ iv_size = mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND); $ encrypted = base64_encode (mcrypt_encrypt (MCRYPT_RIJNDAEL_256, $ key, $ data, MCRYPT_MODE_ECB, $ iv)); returnera $ krypterad; } dekryptera privat funktion ($ data, $ key) {$ salt = 'cH! swe! retReGu7W6bEDRup7usuDUh9THeD2CHeGE*ewr4n39 = E@rAsp7c-Ph@pH'; $ key = substr (hash ('sha256', $ salt. $ key. $ salt), 0, 32); $ iv_size = mcrypt_get_iv_size (MCRYPT_RIJNDAEL_256, MCRYPT_MODE_ECB); $ iv = mcrypt_create_iv ($ iv_size, MCRYPT_RAND); $ decrypted = mcrypt_decrypt (MCRYPT_RIJNDAEL_256, $ key, base64_decode ($ data), MCRYPT_MODE_ECB, $ iv); $ decrypted = rtrim ($ decrypted, "\ 0"); returnera $ dekrypterat; }
Steg 12. Avsluta klass
Här avslutar vi bara klasserna med lockiga parenteser:
Slutklass:
}
Metod 3 av 3: Skapa sidor med sessioner
Steg 1. Använda sessioner med den anpassade sessionshanteraren
Nedan är hur du skulle starta en ny session; du skulle behöva inkludera detta på varje sida du vill komma åt sessionerna, använd den istället för session_start ();
Starta en session:
require ('session.class.php'); $ session = ny session (); // Sätt till true om du använder https $ session-> start_session ('_ s', false); $ _SESSION ['something'] = 'Ett värde.'; echo $ _SESSION ['något'];