3 sätt att skapa ett säkert sessionshanteringssystem i PHP och MySQL

Innehållsförteckning:

3 sätt att skapa ett säkert sessionshanteringssystem i PHP och MySQL
3 sätt att skapa ett säkert sessionshanteringssystem i PHP och MySQL

Video: 3 sätt att skapa ett säkert sessionshanteringssystem i PHP och MySQL

Video: 3 sätt att skapa ett säkert sessionshanteringssystem i PHP och MySQL
Video: 30 глупых вопросов Data Engineer [Карьера в IT] 2024, April
Anonim

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

2238751 1
2238751 1

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.

2238751 2
2238751 2

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.

2238751 3
2238751 3

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

2238751 4
2238751 4

Steg 1. Skapa klass

För att starta en ny klass måste du ange koden nedan:

Ny klass:

klass session {

2238751 5
2238751 5

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'); }

2238751 6
2238751 6

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); }

2238751 7
2238751 7

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; }

2238751 8
2238751 8

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; }

2238751 9
2238751 9

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; }

2238751 10
2238751 10

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; }

2238751 11
2238751 11

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; }

2238751 12
2238751 12

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; }

2238751 13
2238751 13

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; }}

2238751 14
2238751 14

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; }

2238751 15
2238751 15

Steg 12. Avsluta klass

Här avslutar vi bara klasserna med lockiga parenteser:

Slutklass:

}

Metod 3 av 3: Skapa sidor med sessioner

2238751 16
2238751 16

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'];

Rekommenderad: