perl - 如何为 Plack::Middleware::Session 管理的 cookie 设置过期时间?

标签 perl session session-cookies middleware plack

现在我的 app.psgi包含(简化):

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

有效 好的 ,例如:
  • 当用户登录时,我将他的名字存储在服​​务器端存储的 session 文件中,而 Plack::Middleware::Session设置一个简单的 session 状态cookie,
  • 并且当用户关闭浏览器时,cookie 会自动清除(因为 Plack::Session::State::Cookie 默认情况下没有为 cookie 设置任何过期时间)。

  • 现在,我想在我的登录面板中实现“记住我”功能。在这种情况下,不应从浏览器中自动删除 session 状态 cookie。这可以通过使用 expires 来完成。方法来自 Plack::Session::State::Cookie .

    问题:

    如何从我的 $app 更改 cookie 过期时间(由 Session 中间件管理) .换句话说,如何在这里稍微调用 expire 方法:
    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; 
    };
    

    最佳答案

    您不能直接更改到期日期,但您可以强制 session 中间件创建一个具有新到期日期的新 session ,如下所示:

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

    如果用户登录,您无论如何都应该将 ID 更改为 prevent session fixation attacks .见 Cookie::Baker 对于支持的到期日期格式。

    编辑:如果要全局设置默认过期超时,可以手动构建状态对象并通过 expires构造函数的参数:
    builder {
        enable 'Session',
            state => Plack::Session::State->new(
                expires => $timeout_in_seconds,
            );
        $app;
    };
    

    关于perl - 如何为 Plack::Middleware::Session 管理的 cookie 设置过期时间?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29187503/

    相关文章:

    android - 安全和不安全 cookie 之间的区别

    google-chrome-extension - Chrome 扩展忽略 XMLHttpRequest.withCredentials 字段

    perl - Perl 中的 "Not an ARRAY reference"

    java - 浏览器重启java后保持 session

    asp.net - Session_Start 中的 Response.Redirect 不起作用

    php - 如何检查 session 是否已启动并重定向用户?

    jsp - cookie 可以在 session 过期之前过期吗?

    Apache:操作指令未激活 CGI 脚本

    perl - 将所有文档与 Perl 的 Text::DocumentCollection 中的其他文档进行比较

    perl - 如何将可选参数传递给 Perl 函数?