HTTP Session

Web aplikacionet bazohen në protokolin HTTP, i cili është "stateless protocol", që do të thotë se të dhënat (variablat) e një skripte pas përfundimit të ekzekutimit të tij nuk ruhen, kështu që gjatë dërgimit të kërkesës së re - skripta që do të ekzekutohet nuk i ka fare këto të dhëna në dispozicion.

Për t'i ruajtur këto vlera edhe gjatë dërgimit të kërkesave të reja, përdoret mekanizmi i sesioneve. Me anë të sesioneve, të dhënat ruhen në server, në sistemin e fajllave, në databazë apo RAM memorje (Memcached, Redis), prej nga pastaj lexohen nga skriptat tjera.

Konfigurimi

Fajlli i konfigurimit të sesioneve gjendet në config/session.php. Disa vlera mund të definohen edhe në fajllin .env, si në shembullin e mëposhtëm: SESSION_DRIVER, SESSION_LIFETIME, SESSION_COOKIE, SESSION_DOMAIN, SESSION_SECURE_COOKIE .

return [
    'driver' => env('SESSION_DRIVER', 'file'),
    'lifetime' => env('SESSION_LIFETIME', 120),
    'expire_on_close' => false,
    'encrypt' => false,
    'files' => storage_path('framework/sessions'),
    'connection' => null,
    'table' => 'sessions',
    'store' => null,
    'lottery' => [2, 100],
    'cookie' => env(
        'SESSION_COOKIE',
        str_slug(env('APP_NAME', 'laravel'), '_').'_session'
    ),
    'path' => '/',
    'domain' => env('SESSION_DOMAIN', null),
    'secure' => env('SESSION_SECURE_COOKIE', false),
    'http_only' => true,
    'same_site' => null,

];

.env e përcaktojmë drajverin e sesioneve, e që fillimisht ka vlerën file:

SESSION_DRIVER=file

Me file mundësohet ruajtja e të dhënave të sesioneve në formë të fajllave në server, e që për shumicën e aplikacioneve, në veçanti atyre të vogla, ofron performanca të kënaqshme.

02/17/2018  03:40 PM               239 1lGibLvI90KQLaNpoW9m8XrzpgE7oiWXVdAz11oc
02/17/2018  03:19 PM               225 1LlFjcNc6tp8B8omc4OQoffUK5IRT74DLbRAcrW5
02/17/2018  02:11 PM               244 2YZMm0zOkBFkHRfMANF7TuuZcLM2sCM2Z1GrhNsO
02/17/2018  03:26 PM               193 34fG8wv5JAQk8YeWB85FqIguJa0SfgXy7EBl1PaK
02/17/2018  03:48 PM               283 3jHhpwFB8gXG71mAxni141yaik0kVXvyRezoKHVw
02/17/2018  02:35 PM               246 4hgkeF92BtAsZ26qKmyIGTGuc6TFoRSMhXCXcjDr
02/17/2018  01:48 PM               249 5kmReI6Hs7OLRWRuBO1OjlIflBp9DWOC7MzkdjRW
...

Emri i fajllit korrespondon me hash të ID-së së sesionit. Brenda një fajlli të tillë, të dhënat e sesionet ruhen në formë të vargut të serializuar.

SESSION_DRIVER mund t'i ketë këto vlera:

  • file - Të dhënat e sesioneve ruhen si fajlla në folderin storage/framework/sessions.
  • cookie - Të dhënat e sesioneve ruhen në cookie të enkriptuar.
  • database - Të dhënat e sesioneve ruhen në databazë.
  • apc - Të dhënat e sesioneve ruhen në Apc.
  • memcached - Të dhënat e sesioneve ruhen në Redis.
  • redis - Të dhënat e sesioneve ruhen në Redis.
  • array - Të dhënat e sesioneve ruhen në PHP arry dhe nuk persistojnë.

Siç u cek më sipër, sesionet po ashtu mund të ruhen në databazë, për çka nevojitet që si drajver të ceket database.

SESSION_DRIVER=database

Për këtë nevojitet të krijohet tabela sessions me këtë skemë:

Schema::create('sessions', function ($table) {
    $table->string('id')->unique();
    $table->unsignedInteger('user_id')->nullable();
    $table->string('ip_address', 45)->nullable();
    $table->text('user_agent')->nullable();
    $table->text('payload');
    $table->integer('last_activity');
});

Meqë ky migracion vie bashkë me Laravel, na mjafton ta krijojmë tabelën me anë të migracionit:

php artisan session:table

php artisan migrate
  • id - ID e sessionit, është sha1() hash 40 karakterësh p.sh. 1wbfQOwJ1GNCKamjNq4i8zUXwMbcYsvjnXvwQPDN.
  • user_id - Nëse vizitori nuk është i autentikuar, vlera e user_id është NULL, ndërsa për përdoruesit e autentikuar është ID e përdoruesit nga tabela users.
  • ip_address - IP adresa e vizitorit, p.sh. 207.46.13.210.
  • user_agent - Të dhënat e shfletuesit (user agent) që është duke e përdorur vizitori, psh. Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.181 Safari/537.36
  • payload - Në këtë fushë ruhen të dhënat e sesionit, pra vlerat e variablave që na duhen gjatë kërkesave vijuese.
  • last_activity - Koha (timestamp) kur aplikacioni i është qasur atij rreshti të tabelës së sesionit. P.sh. vlera 1523965088 korrespondon me datën GMT: Tuesday, April 17, 2018 11:38:08 AM.

Përdorimi i sesioneve

Marrja e të dhënave

Ekzistojnë dy mënyra për të punuar me sesione në Laravel: ndihmësi global session() dhe instanca e Request.

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;

class UserController extends Controller
{
    public function show(Request $request, $id)
    {
        $value = $request->session()->get('key');
    }
}

Me $request->session()->get('key') lexohet vlerat e anëtarit key të vargut të sesionit.

Në rastet kur një anëtar i vargut mund të mos jetë i inicializuar, pra të mos ta ketë vlerën të caktuar, mund ta definojmë një vlerë standarde (default), si argument të dytë të metodës get:

$value = $request->session()->get('counter', 0);

Nëse vlera standarde (default) kërkon logjikë më komplekse për t'u llogaritur, si argument të dytë e përdorim një Closure:

$value = $request->session()->get('key', function () {
    return 'default';
});

Ky Closure kthen vlerën e kalkuluar me return.

Ndihmësi global i sesionit

Për të lexuar apo shkruar vlerat e vargut të sesionit mund ta përdorim edhe funksionin session(), i cili vepron si ndihmës global (global helper).

$value = session('key');

është ekuivalent me:

$value = $request->session()->get('key');

ndërsa

$value = session('key', 'default');

është ekuivalent me:

$value = $request->session()->get('key', 'default');

Leximi i të gjitha të të dhënave të sesionit

Kur dëshirojmë t'i lexojmë të gjitha të dhënat e sesionit përdorim metodën all().

$data = $request->session()->all();

Determinimi nëse ekziston një anëtar i vargut të sesionit

Për të determinuar nëse një anëtar i vargut të sesionit ekziston, përdorim metodën has(). Kjo metodë kthen true nëse ekziston, ndërsa null nëse nuk ekziston.

if ($request->session()->has('users')) {
    //
}

Për të determinuar nëse një anëtar i vargut të sesionit ekziston, edhe nëse vlera e tij është null, përdoret metoda exists(). Kjo metodë kthen true nëse anëtari është prezent.

if ($request->session()->exists('users')) {
    //
}

Vendosja e të dhënave

Për ta ruajtur një vlerë në sesion, përdoret metoda put(), ose në rastin e ndihmësit global session(), përdoret një varg (array).

$request->session()->put('key', 'value');

// ose

session(['key' => 'value']);

Shtimi i vlerave në vargun e sesionit

Metoda push përdoret për shtimin e një vlere të re një vargu që është anëtar i vargut të sesionit.

$request->session()->push('user.teams', 'developers');

Leximi dhe fshirja e një elementi

Metoda pull() lexon dhe më pastaj fshin një element nga vargu i sesionit.

$value = $request->session()->pull('key', 'default');

Flash Data

Ndonjëherë na duhet të ruajmë vlera në vargun e sesionit vetëm deri në kërkesën e re, apo thënë ndryshe - për një përdorim. Për këtë përdoret metoda flash(). Të dhënat e ruajtura do të jenë në dispozicion vetëm gjatë kërkesës vijuese dhe më pas fshihen.

$request->session()->flash('status', 'Task was successful!');

Nëse megjithatë na duhet ato të dhëna edhe për një kërkesë të mëpastajme, përdoret metoda reflash(). Nëse nuk na nevojiten të gjitha të dhënat, ato që na nevojiten i cekim me metodën keep().

$request->session()->reflash();

$request->session()->keep(['username', 'email']);

Fshirja e të dhënave

Metoda forget() e fshin një të dhënë nga sesioni, respektivisht e fshin një element të vargut të sesionit. Nëse dëshirojmë t'i fshijmë të gjitha të dhënat e sesionit, përdorim metodën flush().

$request->session()->forget('key');

$request->session()->flush();

Regjenerimi i ID-së së sesionit

Regjenerimi i ID-së së sesionit bëhet me metodën regenerate().

$request->session()->regenerate();