如何可靠地检测到过期的Laravel会议?
我正在研究一个可以执行大量AJAX请求的Web客户端。后端用拉拉维尔(Laravel)写。如果后端引发了PHP异常,则后端将JSON响应发送给客户标头显示HTTP错误代码,其主体包含PHP异常的名称。
如果用户不活动一段时间,则HTTP会话到期。这意味着客户端传输的会话ID已被后端丢弃,因此会话ID未知。在这种情况下,我将除Laravel提供适当的PHP异常,例如SessionIdunknown
,session Expecreied
或任何此类内容。这将使Web客户端能够可靠地检测到这种情况并做出相应的反应。
但是,似乎Laravel的会话管理根本不在乎,是否存在会议。该请求可能会在以后失败(如果有一些不可预见的错误),如果呼叫图的某些代码在呼叫图中进一步尝试从会话中加载一个值并失败,因为该值不设置或null
。
步骤调试公布了以下跟踪:
1. Illuminate\Session\Middleware\StartSession::handle
2. Illuminate\Session\Middleware\StartSession::getSession
3. Illuminate\Session\Store::setId
4. Illuminate\Session\Middleware\StartSession::handleStatefulRequest
5. Illuminate\Session\Middleware\StartSession::startSession
6. Illuminate\Session\Store::start
7. Illuminate\Session\Store::loadSession
8. Illuminate\Session\Store::readFromHandler
- 在步骤2中,中间件从请求中读取声明的会话ID(例如,来自客户端发送的cookie)。
- 在步骤3中,中间件在
Store
对象上设置ID,以供以后使用,但这实际上只是一个简单的设置器。这里什么都没发生。 - 在步骤8中,“真实”魔术发生了,
Store
对象试图相对于先前设置的ID加载持久的会话数据。
但是,该代码看起来像
protected function readFromHandler() {
if ($data = $this->handler->read($this->getId())) {
$data = @unserialize($this->prepareForUnserialize($data));
if ($data !== false && ! is_null($data) && is_array($data)) {
return $data;
}
}
return [];
}
Unerialize
的任何错误都会通过@
-operator抑制。如果出现任何问题,即未进行的
已返回false
,null
或任何不是数组的东西,该方法默默地返回空数组[]
。因此,如果会话不存在(错误情况),或者如果会话简单地为空,则无法区分会话(没有错误)(没有错误)。
请告诉我我正在犯错!如何可靠地检测后端中的不存在或过期的会话并返回A 一致错误消息?
我本来可以预期Laravel的以下行为:
- 如果客户端未通过cookie发送会话ID,则创建新的会话并将新创建的会话ID返回给客户set-cookie。
- 如果客户端通过cookie发送会话ID,并且会话ID存在,请继续进行。
- 如果客户端通过cookie发送会话ID,并且会话ID不存在或无法加载,请停止进一步处理请求并返回错误响应。
I am working on a web client which does a lot of AJAX request. The backend is written in Laravel. If the backend throws a PHP exception, the backend sends a JSON response to the client whose header shows a HTTP error code and whose body includes the name of the PHP exception.
If a user has been inactive for a while, the HTTP session expires. This means that the session ID transmitted by the client has been discarded by the backend and thus the session ID is unknown. I would have excepted Laravel to throw a proper PHP exception in this case, e.g. something like SessionIdUnknown
, SessionExpired
or anything of that sort. This would enable the web client to reliably detect this situation and react accordingly.
However, it seems as if Laravel's session management does not care at all, whether the session exists or not. The request will potentially fail later (with some unforeseeable error), if some code further down the call graph tries to load a value from the session and fails, because the value is unset or null
.
Step debugging unveiled the following trace:
1. Illuminate\Session\Middleware\StartSession::handle
2. Illuminate\Session\Middleware\StartSession::getSession
3. Illuminate\Session\Store::setId
4. Illuminate\Session\Middleware\StartSession::handleStatefulRequest
5. Illuminate\Session\Middleware\StartSession::startSession
6. Illuminate\Session\Store::start
7. Illuminate\Session\Store::loadSession
8. Illuminate\Session\Store::readFromHandler
- In step 2, the middleware reads the claimed session ID from the request (e.g. from the cookie sent by the client).
- In step 3, the middleware sets the ID on the
Store
object for later use, but that is really only a simply setter; nothing else happens here. - In step 8 the "real" magic happens, the
Store
object tries to load the the persisted session data with respect to the previously set ID.
However, the code looks like that
protected function readFromHandler() {
if ($data = $this->handler->read($this->getId())) {
$data = @unserialize($this->prepareForUnserialize($data));
if ($data !== false && ! is_null($data) && is_array($data)) {
return $data;
}
}
return [];
}
Any error by unserialize
is suppressed via @
-operator. If anything goes wrong, i.e. unserialized
has returned false
, null
or anything which is not an array, the method silently returns the empty array []
. So we cannot distinguish, if the session did not exist (error case) or if the session is simply empty because no data has previously been stored (no error).
Please tell me that I am erring! How do I reliably detect an non-existing or expired session in the backend and return a consistent error message?
I would have expected the following behavior by Laravel:
- If the client does not sent a session ID via a cookie, then create a new session and return the newly created session ID back to client with set-cookie.
- If the client sends a session ID via a cookie and the session ID exist, then proceed.
- If the client sends a session ID via a cookie and the session ID does not exist or cannot be loaded, stop further processing of the request and return an error response.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论