菲尼克斯集团如何cookie数据



我正试图将一些数据存储到会话存储中,但我遇到了与这家伙相同的cookie错误,cookie超过了4096的系统字节限制。

这看起来很直接,不要试图在会话中存储超过系统限制的内容。是的,但我不想这么做。很明显,cookie超过4096字节,我添加的内容导致它溢出,但这并不能解释数据在哪里

我试图存储的数据只有1500字节。事实上,正在保存的整个会话是1500字节(出错的会话(。这远未达到溢出极限。因此,这意味着有一点是肯定的:存储在conn内部的:plug_session中的数据并不是存储在会话cookie中的唯一数据。

这是抛出CookieOverflow的会话错误:

:plug_session => %{
"_csrf_token" => "XmE4kgdxk4D0NwwlfTL77Ic62t123123sdfh1s",
"page_trail" => [{"/", "Catalog"}, {'/', "Catalog"}],
"shopping_cart_changeset" => #Ecto.Changeset<
action: nil,
changes: %{
order: #Ecto.Changeset<
action: :insert,
changes: %{
address: #Ecto.Changeset<
action: :insert,
changes: %{
address_one: "800 Arola Drive, apt 321, apt 321",
address_two: "apt 321",
city: "Wooster",
company: "Thomas",
country: "US",
name: "user one",
phone: "3305551111",
state: "WV",
zip_code: "44691"
},
errors: [],
data: #FulfillmentCart.Addresses.Address<>,
valid?: true
>,
priority: false,
shipping_method: #Ecto.Changeset<
action: :insert,
changes: %{id: 2, is_priority?: false, name: "3 Day Select"},
errors: [],
data: #FulfillmentCart.ShippingMethods.ShippingMethod<>,
valid?: true
>
},
errors: [],
data: #FulfillmentCart.Orders.Order<>,
valid?: true
>
},
errors: [],
data: #FulfillmentCart.ShoppingCarts.ShoppingCart<>,
valid?: true
>,
"user_id" => 8
},

事实上,我遵循了这个关于解码phoenix会话cookie的指南,并且我在出错之前得到了会话。

这给了我:

iex(8)> [_, payload, _] = String.split(cookie, ".", parts: 3)
["SFMyNTY",
"g3QAAAADbQAAAAtfY3NyZl90b2tlbm0AAAAYWU92dkRfVDh5UXlRTUh4TGlpRTQxOFREbQAAAApwYWdlX3RyYWlsbAAAAAJoAm0AAAABL20AAAAHQ2F0YWxvZ2gCawABL20AAAAHQ2F0YWxvZ2ptAAAAB3VzZXJfaWRhCA",
"Ytg5oklzyWMvtu1vyXVvQ2xBzdtMnS9zVth7LIRALsU"]
iex(9)> {:ok, encoded_term } = Base.url_decode64(payload, padding: false)
{:ok,
<<131, 116, 0, 0, 0, 3, 109, 0, 0, 0, 11, 95, 99, 115, 114, 102, 95, 116, 111,
107, 101, 110, 109, 0, 0, 0, 24, 89, 79, 118, 118, 68, 95, 84, 56, 121, 81,
121, 81, 77, 72, 120, 76, 105, 105, 69, 52, 49, ...>>}
iex(10)> :erlang.binary_to_term(encoded_term)
%{
"_csrf_token" => "YOvvD_T8yQyQMHxLiiE418TD",
"page_trail" => [{"/", "Catalog"}, {'/', "Catalog"}],
"user_id" => 8
}
iex(11)>

这是127个字节,所以添加1500个字节不是问题。这是会话中没有表示的另一种存储分配。那是什么?

我对:plug_session中文本本身字节大小的假设是正确的,但cookie溢出的原因不是因为:plug_session中解码文本的字节大小太大,而是因为:plug_session的编码版本太大。我通过创建多个cookie并查看数据的字节大小来解决这个问题。

保存新的cookie

conn = put_resp_cookie(conn, "address", 
changeset.changes.order.changes.address.changes, sign: true)

获取保存的cookie

def get_resp_cookie(conn, attribute) do
cookie = conn.req_cookies[attribute]
case cookie != nil do
false ->
{:invalid, %{}}
true ->
[_, payload, _] = String.split(cookie, ".", parts: 3)
{:ok, encoded_term } = Base.url_decode64(payload, padding: false)
{val, max, max_age} = :erlang.binary_to_term(encoded_term)
{:valid, val}
end
end

get_resp_cookie/2模式匹配

address_map = case Connection.get_resp_cookie(conn, "address") do
{:invalid, val} -> IO.puts("Unable to find cookie.");val
{:valid, val} -> val
end

当我发布这篇文章时,我对保存数据的方式做了一些更改。也就是说,我现在存储的是一个变更映射,而不是实际的变更集。。。这意味着这个环节很可能一直对我有效。

我认为这个问题的答案是编码的%Ecto.Changeset{}太大了,cookie无法容纳
如果您使用此解决方案,请小心,您必须自己管理新创建的cookie。

最新更新