2015-03-21 7 views
7

Теперь мой app.psgi содержит (упрощенно):Как установить время истечения срока действия файла cookie, управляемого Plack :: Middleware :: Session?

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

Позже, в $app я использую:

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

Он работает ОК, например:

  • когда пользователь вошел в систему, я сохраняю его имя в хранимом файле сеанса на стороне сервера, а Plack::Middleware::Session устанавливает s imple session-state-cookie,
  • и когда пользователь закрывает браузер, cookie автоматически очищается (потому что Plack::Session::State::Cookie по умолчанию не установил никаких истечений для файла cookie).

Теперь я хочу реализовать функцию «Запомнить меня» на моей панели входа. В этом случае файл sesion-state-cookie не должен автоматически удаляться из браузера. Это можно сделать, используя метод expires из Plack::Session::State::Cookie.

Вопрос:

Как я могу изменить срок действия куков (управляемый Session промежуточного слоя) из моего $app. С другими словами, как назвать истекают метод несколько здесь:

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 

Если кому-то нужно, вот рабочий пример.

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

ответ

5

Вы не можете изменить дату истечения срока действия напрямую, но вы можете заставить сессионный промежуточное программное обеспечение, чтобы создать новую сессию с новым сроком действия, как это:

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

Если пользователь входит в систему, вы должны изменить идентификатор в любом случае до prevent session fixation attacks. См. Cookie::Baker для поддерживаемых форматов даты истечения срока действия.

EDIT: Если вы хотите установить тайм-аут окончания срока действия по умолчанию во всем мире, вы можете создать объект состояния вручную и передать параметр expires конструктору:

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

Хотя я ожидал несколько вызовов методов, это * *работает**. Мой вопрос в том, где это документировано? Потому что в Plack :: Middleware :: Session [задокументированы некоторые подразделы] (https://metacpan.org/pod/Plack::Middleware::Session#PLACK-REQUEST-OPTIONS) для 'psgix.session.options' но «expires» отсутствует. (Здесь только «expire»/без множественного числа (-ов)/что означает аннулирование сеанса). Так действительно интересно, откуда вы это знаете. Покопавшись в источниках модуля? В любом случае ** спасибо ** очень. – kobame

+2

@kobame Да, я знаю это, глядя на исходный код. Я открыл проблему [GitHub] (https://github.com/plack/Plack-Middleware-Session/issues/33) относительно отсутствующей документации. – nwellnhof

+0

Я хотел сказать спасибо за ответ; собираюсь попробовать это в своем приложении. Проблема github не имела никакой активности, и у рамки, которую я использовал (Kelp), похоже, нет никаких вариантов. – saberworks