3

我有一个 Mojolicious 应用程序和一个用于身份验证的桥梁。这是我的场景:
我在数据库中有一组标准错误响应,我通过传入一个值进行查询,比如返回一个带有详细错误响应的 404。数据库将具有与错误相对应的常见详细信息,而其他用户特定的详细信息(例如 ip 和用户名)则从控制器获取。请看一下这个链接关于如何构建错误响应。我有一个助手,它获取控制器实例和错误代码以生成所需的响应。我使用控制器对象通过包含错误响应的表的结果集来查询数据库。通过控制器,我还获得了创建响应所需的用户特定详细信息。然后创建响应,将其发送回控制器,然后作为 Json 返回。
我的问题是注销,我设置$self->session(expires => 1)了使会话无效。在尝试再次注销时,我使用控制器访问帮助程序构建错误响应并将其发送给客户端。现在,通过以下检查,任何访问任何 URI 的尝试对于第一次尝试都是徒劳的。

unless($self->session('user')) {
    my $res = Controller::Helper->error_res($self, 403);
    $self->render_json($res, status => $res->{httpstatuscode});
    return;
    }

此检查第一次有效,但是当我再次尝试访问资源(任意次数)时,此检查失败并且无需登录即可访问资源。当我查看 cookie 时,会创建一个新的 cookie。我在哪里错了?处理此类问题的最佳方法是什么?辅助函数看起来像这样

error_res{ 
    my($self,$c,$res) = @_; 
    my @arref = $c->db->resultset('Errorcode')->select_row($res);
    my $ref=$arref[0];
    $ref->{user}=$c->session->{user}->{name};
    $ref->{request}=$c->req->method."".join("\\",$c->req->url->path);
    $ref->{time}=scalar localtime();
    return $ref;
}

数据库中res可以识别特定错误的位置和 id。

那么,它是否与助手中仍然可用的控制器的引用有关?当我$c在助手中取消定义时,它没有帮助。
编辑1:我在这里遗漏了一些观点,这是正确的方法吗?
编辑 2:我在注销时使用户无效。当用户再次尝试注销时,我会返回一个错误,其中包含有关该错误的其他信息。但是在创建有关错误的附加信息时,会创建一个没有用户信息的新会话。如果我执行以下操作,则不会发生这种情况

unless($self->session('user')) {
    $self->render_json("message:User has not logged in", status => 403);
    return;
}
4

2 回答 2

3

所以我想出了答案,奇怪的行为是由于 perl 的自动生存功能。它涉及数据结构的动态创建。就我而言,我尝试通过会话 cookie 获取用户名

$ref->{user}=$c->session->{user}->{name}; 

当用户未登录时,会话中未设置密钥,但我在创建错误响应时user尝试通过此密钥。name这导致创造user没有价值。检查user密钥是否存在解决了该问题。

于 2013-01-23T20:42:03.923 回答
1

阅读评论后,我相当确定该框架的行为符合预期。可能需要更改应用程序逻辑(如编辑 2 中所示)。

原因是,会话只是一个 hashref,序列化为 JSON,签名并存储在 cookie 中。如果您创建密钥,那么它就在那里。我不知道还能告诉你什么。

是的,在前一个会话 cookie 到期后立即创建一个新的会话 cookie。这是框架所必需的,也是完全可以预料的。

于 2013-01-23T18:16:01.020 回答