ipa*_*aus 19 php cookies session laravel
我在Laravel中使用cookie会话驱动程序很困难.
我有一个简单的表格,有一个验证到位.这是我保存此表单数据的方法:
public function store()
{
$this->validate(request(), [
'name' => 'required',
'title' => 'required',
'description' => 'required|max:600',
'image' => 'required|file|mimes:jpeg,png',
]);
$member = TeamMember::create(request()->all());
$member->addImage(request()->file('image'));
return redirect()->route('backoffice.team-members');
}
Run Code Online (Sandbox Code Playgroud)
很简单.
问题是,当使用cookie会话驱动程序时,如果我使用长度为1024个字符的描述保存此表单,我将被重定向回但没有闪存数据,并且$errors
视图中没有下一个要处理的请求.
例:
这是使用此行后的POST:
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce gravida eros ut leo commodo luctus. Nulla neque dui, laoreet quis felis in, porta tincidunt felis. Phasellus in lacus et sem condimentum ornare. Praesent vitae nisi tempus, gravida tortor eu, convallis dui. Cras lacinia posuere scelerisque. Vestibulum tincidunt purus id sollicitudin varius. Sed eros urna, mattis nec nunc eu, finibus suscipit ipsum. Aliquam varius faucibus congue. Vivamus convallis imperdiet sem a commodo. Proin cursus feugiat sem a pharetra. Curabitur rhoncus non quam sit amet lacinia. Sed ut nisl id odio faucibus vehicula vel ut erat. Vestibulum ut iaculis magna. Quisque sit amet massa sodales, suscipit nisl eu, dapibus elit. Morbi posuere ligula pretium commodo semper. Nam odio elit, rutrum finibus tortor eget, viverra viverra metus. Proin tincidunt tempor ex pretium rhoncus. Proin egestas erat sed eros congue, mollis gravida magna bibendum. Pellentesque vel bibendum nunc. Orci varius natoque penatibus et magnis dis viverra fusce.
Run Code Online (Sandbox Code Playgroud)
在描述字段中.准确地说是1024字节.
相反,如果我只是填充一些虚拟数据,但没有太疯狂:
如果我将会话驱动程序更改为file:
... 有用.
但这并不能解决我的问题.我确实需要使用cookie驱动程序进行会话,因为生产网站在3个不同的数据中心运行,以实现高可用性.使用cookie进行会话允许用户点击3个服务器中的任何一个,并继续使用它的请求,而无需使用任何粘性会话或任何中央会话驱动程序.
使用数据库作为驱动程序 - 也在具有HA的群集中 - 不是一个选项,因为这是一个真正高流量的网站,并且这将是每个请求的写入,这听起来根本没有吸引力.我想不惜一切代价阻止这种情况.
无论如何这可以解决?
我必须说这是网站的后台,但很快前端的用户也可以在textarea中写入超过1024个字符...所以如果我只是改变后台的驱动程序没有帮助,如我们将为我们的用户遇到同样的问题.
Cy *_*nol 18
该cookie的会话驱动程序不适用于必须存储在用户的会话数据的任何显著量的应用程序.浏览器通常将存储在一个cookie中的数据限制为大约4 KB(4096字节).正如我们所发现的,我们可以通过尝试在会话cookie中存储1024个字符长的字符串来轻松耗尽此容量 - 问题中的"Lorem ipsum ..."字符串仅包含ASCII字符,并且每个ASCII字符使用4个字节,所以1024×4 = 4096个字节.
我们可以看到,当我们需要在一个会话cookie中存储其他项目时,如PHP值的序列化元数据,或者当数据包含每个消耗超过4个字节的UTF-8字符时,我们很快就会开始耗尽空间字符.要继续使用cookie来存储大于4 KB的会话数据,我们需要编写一个自定义会话驱动程序,为每个响应分隔多个cookie的会话数据,然后在每个请求上重新组合它们.有充分的理由,没有现有的包这样做,我知道.这让我想到了下一点......
我强烈建议不要使用cookie来存储完整的会话(而不仅仅是会话ID).此方法可能会暴露安全漏洞,增加请求和响应的开销(包括对同一域上的静态资产的请求),使数据失去同步的风险(右键单击应用程序选项卡→ 复制以查看发生的情况),使测试和调试复杂化并导致问题存储某些类型的数据时
对于问题中的分布式应用程序,我们有四个选项:
我认为我们可以合理地消除第四种选择.除非我们有充分的理由避免使用前三种方法,而对于我们通常不会使用的典型应用程序,我们无法证明构建系统来回传输会话数据所需的工作量,复杂性和开销.当前三个选项是标准的,广泛接受的解决方案时,HTTP.
根据问题中的信息,听起来像你已经理解了其他三个选项背后的概念和含义,所以我不会详细解释每个选项的解释(但是如果我应该做的话请做出评论让我知道).
对于没有先进的基础设施需求的应用程序,我建议第三种方法:粘性会话.这些设置相对容易,通常需要在负载均衡器上进行配置,以便客户端启动与应用程序服务器的会话后,负载均衡器会将任何后续请求路由到同一服务器,直到会话结束.为了实现高可用性,我们可以将此方法与为数据中心之间的主从复制配置的Redis会话驱动程序和Redis服务器以及可选的Redis Sentinel自动执行故障转移相结合.Redis非常适合会话数据,并且提供比关系数据库更好的性能.如果我们在每个数据中心都有多个应用程序实例,Redis会为一个站点上的所有实例提供会话数据的中心位置.
为了完整性并直接回答问题,这里概述了创建基于cookie的会话驱动程序所需的开发,该驱动程序处理大于4 KB的会话数据.我再次推荐上述其他方法之一:
首先,我们需要创建一个实现PHP的新类SessionHandlerInterface
(检查Laravel的cookie会话处理程序的起点 - 我们可以扩展这个类).
write()
此类的方法将需要序列化会话$data
,然后将数据拆分为小于4 KB的块(对于某些浏览器,少于4093字节).请务必考虑多字节字符.在拆分数据之前,如果会话包含敏感信息或者我们不希望聪明的用户弄乱这些值,我们可能还希望对其进行加密.然后,该方法应为会话数据的每个块添加新的cookie .每个cookie都需要在其名称中包含序列,我们可以添加一个包含块数的附加cookie.
该read()
方法将反向执行这些操作.首先,它将使用包含块数的cookie的值重新组合请求中的cookie中的每个块,然后,如果我们加密它,则可选地解密数据.
该destroy()
方法应清除包含块的每个cookie的内容.
然后我们将为会话驱动程序选择一个名称,例如cookie-extended
,在服务提供程序的boot()
方法中,使用以下命令将其注册为可用的驱动程序:
Session::extend('cookie-extended', ...);
Run Code Online (Sandbox Code Playgroud)
我们需要在config/session.php或.env中指示应用程序将新驱动程序用于用户会话.
如果您决定沿着这条路走下去,请务必在您计划支持的每个浏览器中测试实现,因为不同的浏览器会对Cookie的大小和数量施加限制.即使我们增加了可以存储为cookie的会话数据量,我们仍然限制为浏览器每个域接受的最大cookie数量.
最后要注意的是,在数据库中存储会话可能不会像您想象的那样影响性能.在投入多个小时优化以解决可能不是真正问题的问题之前,可能值得测量这个简单解决方案所产生的实际负载.
浏览器有cookie限制.当您cookie
用作会话驱动程序时,浏览器存储cookie太大.你可以在这里查看浏览器cookie限制http://browsercookielimits.squawky.net/
建议:
使用redis
作为会议的驱动程序.
步骤:
1.安装Redis服务器后,添加predis/predis
包:
composer require predis/predis
Run Code Online (Sandbox Code Playgroud)
2.更改配置文件config/database.php
:
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
],
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
966 次 |
最近记录: |