2015-03-21 15 views
7

Ora il mio app.psgi contiene (semplificato):Come impostare la scadenza per un cookie gestito da Plack :: Middleware :: Session?

builder { 
     enable 'Session', store => 'File'; #default uses Plack::Session::State::Cookie 
     $app; 
}; 

Più tardi, nel $app sto usando:

my $req = Plack::Request->new($env); 
my $session = $req->session(); #returns env->{'psgix.session'} 
$session->{user} = "name"; 

E funziona ok, ad esempio:

  • quando il l'utente ha effettuato l'accesso, memorizzo il suo nome nel file di sessione memorizzato sul lato server e il Plack::Middleware::Session imposta una s imple session-state-cookie,
  • e quando l'utente chiude il browser, il cookie viene automaticamente cancellato (perché il Plack::Session::State::Cookie per impostazione predefinita non ha impostato alcuna scadenza per il cookie).

Ora, voglio implementare la funzione "Ricordami" nel mio pannello di login. In questo caso, il cookie sesion-state non dovrebbe essere rimosso automaticamente dal browser. Questo può essere fatto utilizzando il metodo expires da Plack::Session::State::Cookie.

La domanda:

Come posso cambiare la scadenza dei cookie (gestito dalla Session middleware) dal mio $app. Con altre parole, come chiamare il metodo scadono un po 'qui:

my $req = Plack::Request->new($env); 
my $session = $req->session(); #returns env->{'psgix.session'} 
$session->{user} = "name"; 
my $cookie_state = WHAT_TO_DO_HERE_TO_GET; #the current Plack::Session::State::Cookie object 
$cookie_state->expire(86400*14); #expire in two weeks 

Se qualcuno ha bisogno, ecco un esempio di lavoro.

use strict; 
use warnings; 
use Plack::Request; 
use Plack::Response; 
use Plack::Builder; 
use Data::Dumper; 

my $app = sub { 
    my $env = shift; 
    my $req = Plack::Request->new($env); 
    my $session = $req->session; 
    my $res = Plack::Response->new(200); 
    $res->content_type('text/html'); 
    my $link = $session->{user} 
      ? q{ <a href="/logout">logout</a>} 
      : q{ <a href="/login">login</a>} 
      ; 
    $res->body(["Session user:", $session->{user}, "<br>$link"]); 
    return $res->finalize; 
}; 

my $login = sub { 
    my $env = shift; 
    my $req = Plack::Request->new($env); 
    my $session = $req->session; 

    $session->{user} = "some"; 
    #how to set here the session-state-cookie expiration? 

    my $res = Plack::Response->new(); 
    $res->redirect("/", 302); 
    return $res->finalize; 
}; 

my $logout = sub { 
    my $env = shift; 
    my $req = Plack::Request->new($env); 
    my $session = $req->session; 
    delete $session->{user}; 
    my $res = Plack::Response->new(); 
    $res->redirect("/", 302); 
    return $res->finalize; 
}; 

builder { 
    enable 'Session', store => 'File'; 
    mount "/login" => $login; 
    mount "/logout" => $logout; 
    mount "/favicon.ico" => sub { return [ 404, ['Content-Type' => 'text/html'], [ '404 Not Found' ] ] }; 
    mount "/" => $app; 
}; 

risposta

5

Non è possibile modificare la data di scadenza direttamente, ma è possibile forzare il middleware sessione per creare una nuova sessione con una nuova data di scadenza in questo modo:

$env->{'psgix.session.options'}{change_id} = 1; 
$env->{'psgix.session.options'}{expires} = $my_expires; 

Se un utente accede, dovresti comunque modificare l'ID a prevent session fixation attacks. Vedi Cookie::Baker per i formati di data di scadenza supportati.

EDIT: Se si desidera impostare il timeout di scadenza predefinita a livello globale, si può costruire l'oggetto Stato manualmente e passare il parametro expires al costruttore:

builder { 
    enable 'Session', 
     state => Plack::Session::State->new(
      expires => $timeout_in_seconds, 
     ); 
    $app; 
}; 
+1

Anche se mi aspettavo alcune chiamate di metodo, esso * *lavori**. La mia domanda è, dove è documentato? Perché in Plop :: Middleware :: Session [sono documentate alcune sottochiavi] (https://metacpan.org/pod/Plack::Middleware::Session#PLACK-REQUEST-OPTIONS) per 'psgix.session.options' ma manca 'scade'. (Qui solo il 'expire'/senza il plurale (s)/cosa è per invalidare la sessione). Quindi mi chiedo davvero da dove lo sai. Scavando nelle sorgenti del modulo? Comunque ** grazie davvero. – kobame

+2

@kobame Sì, lo so osservando il codice sorgente. Ho aperto un [problema GitHub] (https://github.com/plack/Plack-Middleware-Session/issues/33) relativo alla documentazione mancante. – nwellnhof

+0

Volevo dire grazie per la risposta; andando a fare un tentativo nella mia app. Il problema github non ha avuto alcuna attività e il framework che ho usato (Kelp) non sembra avere alcuna opzione intorno a questo. – saberworks