由于各种原因,我厌倦了 ASP.NET 会话状态,我正在尝试自己做(很快就会出现一个单独的问题,与我为什么厌倦以及自己做这件事是否可行有关,但现在让我们假设这是)。
撇开安全问题不谈,跟踪会话似乎只涉及存储带有 guid 的 cookie 并将该 guid 与数据库中的一个小型“会话”表相关联,该表以 guid 为键并包含少量用于跟踪超时的字段对于链接到注册用户的会话,链接到用户表中的主键。
但我对 cookie 的细节感到困惑,以防用户的浏览器未设置为接受 cookie。在我看来,每次用户访问任何启用了会话状态的页面时,ASP.NET 都必须确定浏览器是否支持 cookie。如果已经有一个随请求一起发送的会话 cookie,显然它知道 cookie 已被接受。
如果没有,似乎需要检查,据我了解,这涉及尝试编写 cookie 并重定向到尝试读取 cookie 的页面。因此,当关闭 cookie 的用户访问站点的多个页面时,ASP.NET
(a) 必须对用户访问的每个页面执行此往返测试,或者
(b) 必须假设浏览器接受cookies 并为每个页面上的用户创建一个带有(临时)会话 ID 的记录——如果会话状态应该是持久的,那么似乎必须将该初始会话 ID 写入每个页面上的数据库。
但是 (a) 听起来很疯狂,(b) 听起来也很疯狂,因为我们会快速积累所有这些单页会话的会话 ID。因此,我认为必须有一些其他技巧/启发式方法用于知道何时进行往返测试和/或何时实际为会话创建记录。
我的困惑有错吗?
(需要明确的是,我不是在谈论在 ASP.NET 的可插入会话状态系统中实现自定义存储解决方案。我是在谈论完全跳过 ASP.NET 的会话状态系统。我的问题是此问题的更详细版本: 在 ASP.NET 中实现自己的会话管理。)
For various reasons I am fed up with ASP.NET session state and I'm trying to do it myself (separate question coming soon related to why I'm fed up and whether it's feasible to do it myself, but for now let's assume that it is).
Security concerns aside, it seems like tracking sessions involves little more than storing a cookie with a guid and associating that guid with a small "sessions" table in the database, which is keyed on the guid and contains a small number of fields to track timeout and to link to the primary key in the user's table, for those sessions that are linked to registered users.
But I'm stuck on a detail with the cookie, in the case the user's browser is not set to accept cookies. It seems to me that each time a user accesses any page that has session state enabled, ASP.NET must determine whether the browser supports cookies. If there already is a session cookie sent with the request, obviously it knows cookies are accepted.
If not, it seems like it needs to check, which as I understand it involves trying to write a cookie and redirecting to a page that tries to read the cookie. So it seems, when a user with cookies turned off visits several pages of a site, that ASP.NET
(a) has to do this round-trip test for every page the user visits, or
(b) has to assume the browser accepts cookies and create a record with a (provisional) session id for the user on each page -- and if session state is supposed to be persistent, it seems it has to write that initial session id to the database on each page.
But (a) sounds crazy and (b) sounds crazy also, since we would quickly accumulate session ids for all these single-page sessions. So I'm thinking there must be some other trick/heuristic that is used to know when to do the round-trip test and/or when to actually create a record for the session.
Am I wrong to be perplexed?
(To be clear, I'm not talking about implementing a custom storage solution within ASP.NET's pluggable session state system. I'm talking about skipping ASP.NET's session state system entirely. My question is a more detailed version of this one: Implementing own Session Management in ASP.NET.)
发布评论
评论(2)
会话行为是通过 web.config 中的 sessionState 元素设置的。在 sessionState 元素中, HttpCookieMode 可以设置为
UseUri、UseCookies、AutoDetect、UseDeviceProfile 之一
。UseUri 和 UseCookies 明确告诉 ASP.NET 如何处理存储会话标识符。如果使用 UseDeviceProfile,则行为取决于用户代理是否支持 cookie(而不是它们是否启用)。
AutoDetect 是您感兴趣的有趣案例。了解 ASP.NET 无 Cookie 功能的工作原理。在那篇文章中,您将看到他们进行了 5 种不同的检查。正如您提到的,其中一项检查是设置 cookie 并进行重定向以查看 cookie 是否存在。如果 cookie 存在,则浏览器支持 cookie,并且设置了 sessionID cookie。然而,这并不是对每个请求都执行的,因为他们在尝试重定向之前所做的另一项检查是检查是否存在任何 cookie。由于在初始 set-cookie 和重定向之后,将设置 sessionID cookie,因此 cookie 的存在让 ASP.NET 知道支持 cookie,并且不需要进一步的 set-cookie 和重定向。
Session behaviour is set through the sessionState element in web.config. In the sessionState element the HttpCookieMode can be set to one of
UseUri, UseCookies, AutoDetect, UseDeviceProfile
.UseUri and UseCookies tell ASP.NET explicitly how to handle storing the session identifier. If UseDeviceProfile is used then the behavior is determined by whether the user agent supports cookies (not whether they are enabled or not).
AutoDetect is the interesting case that you are interested in. How ASP.NET is handling the auto detection is explained in Understand How the ASP.NET Cookieless Feature Works. In that article you will see that they have 5 different checks they do. One of the checks is, as you mention, to set a cookie and do a redirect to see if the cookie exists. If the cookie exists, then the browser supports cookies and the sessionID cookie is set. However, this is not done on every request because another check they do before tring to redirect is is check to for the existence of any cookies. Since after the initial set-cookie and redirect the sessionID cookie will be set then the existence of the cookie lets ASP.NET know that cookies are supported and no further set-cookie and redirects are required.
好吧,cookie 是网络身份验证的标准机制。您有什么理由不想使用它们吗?你确定你不是想在没有问题的地方发明一个问题吗?
据我所知,大多数严肃的网站都要求浏览器接受 cookie,以便对用户进行身份验证。可以肯定地假设每个现代浏览器都支持它们。
有一篇关于 cookieless ASP.NET 的有趣文章,您应该阅读。
编辑:
@okw:默认情况下,会话状态由 ASP.NET 进程内保存(读取:在内存中)。除非配置明确告知将会话存储在数据库中(SQL Server 是开箱即用的支持),否则这不会导致数据库命中。过时的会话状态将从进程内存储中清除。不幸的是,使用默认的 ASP.NET 设置,每个无 cookie 请求都将导致创建一个新会话。
以下是可用会话存储选项的详细比较:http://msdn.microsoft。 com/en-us/library/ms178586.aspx。
Well, cookies are a standard mechanism of web authentication. Do you have any reason at all why you wouldn't want to use them? Are you sure you're not trying to invent a problem where there isn't any problem?
Most serious websites I know of require the browser to accept cookies in order for the user to be authenticated. It's safe to assume that every modern browser supports them.
There's an interesting article about cookieless ASP.NET that you should read.
EDIT:
@o.k.w: By default the session state is kept by ASP.NET in-process (read: in memory). Unless told explicitly by the configuration to store the session in the database (SQL Server is supported out-of-the-box), this won't result in a database hit. The stale session states will get purged from the in-process storage. Unfortunately, with default ASP.NET settings every cookieless request will result in a new session being created.
Here's a detailed comparison of available session storage options: http://msdn.microsoft.com/en-us/library/ms178586.aspx.