ASP.Net 将用户数据存储在 Auth Cookie 中
Posted
技术标签:
【中文标题】ASP.Net 将用户数据存储在 Auth Cookie 中【英文标题】:ASP.Net Store User Data in Auth Cookie 【发布时间】:2010-11-07 09:51:44 【问题描述】:我想在 auth cookie 的用户数据部分存储一些数据,例如用户昵称和用户 ID(表主键)。我这样做的原因是在浏览器关闭时保留这些数据,而无需用户重新登录。
编辑:哎呀!意识到我没有很好地解释自己。我不是试图根据他们的 cookie 重新验证用户。用户已经通过 ASP.Net 的会员系统进行身份验证 - 这部分很好。我的问题是,如果我想显示用户的昵称,例如,我必须触发另一个 SQL 查询,然后将其存储在会话中。我认为将这些信息存储在 UserData 部分的 auth cookie(同样,ASP.Net 已经创建的那个)中是有意义的,这似乎是为此目的而创建的。
我不想使用个人资料,因为我有自己的包含个人资料数据的用户表,我需要一个轻量级的解决方案。
在 auth cookie 的用户数据部分中对这些数据进行编码的好方法是什么?我在考虑序列化,但这可能是矫枉过正。我是不是走错路了?
【问题讨论】:
【参考方案1】:我在这里写了一篇关于如何做到这一点的深入教程:
http://www.danharman.net/2011/07/07/storing-custom-data-in-forms-authentication-tickets/
这维护了加密和认证,并使用json将一个类序列化到UserData字段中。
编辑:
博客已不存在,可以在on the web archive here找到存档。
博客摘要:
获取现有的 cookie 和身份验证票
HttpResponse response = HttpContext.Current.Response;
bool rememberMe = true;
var cookie = FormsAuthentication.GetAuthCookie(name, rememberMe);
var ticket = FormsAuthentication.Decrypt(cookie.Value);
定义您的自定义数据(确保它可序列化为 json)
var userData = new YourUserClass(...);
使用您的数据和现有的身份验证票设置创建新的身份验证票
var newTicket = new FormsAuthenticationTicket(ticket.Version,
ticket.Name,
ticket.IssueDate,
ticket.Expiration,
ticket.IsPersistent,
userData.ToJson(), //This is where you'd set your user data
ticket.CookiePath);
var encTicket = FormsAuthentication.Encrypt(newTicket);
将您的自定义票证设置为 cookie 并添加到响应中
cookie.Value = encTicket;
response.Cookies.Add(cookie);
【讨论】:
很棒的解决方案。即使没有 json 序列化部分,这也是设置 UserData 字符串和维护其他默认/配置值的好方法,尽管表单身份验证的 API 很糟糕。 您的回答似乎完全符合我当时的意图!谢谢! 如果它总结了你的帖子并链接到它,这个答案会更有用。如果您的网络服务器被公共汽车撞到,此答案将不再有用。 @RichardGarside 好点。这似乎是这种情况,因为链接现在显示一个空白页面。 不确定发生了什么,因为我必须点击刷新才能加载它,但现在看起来还可以。我将弹出 wordpress 并查看它是否将其排序为它可能与页面缓存插件有关。至于粘贴整篇文章,它很长而且必然,所以我看不出有一种合理的方法可以缩短它以适应这里的答案。【参考方案2】:显然我走对了:http://www.asp.net/learn/security/tutorial-03-vb.aspx(第 4 步:第 4 步:在票证中存储其他用户数据)
【讨论】:
【参考方案3】:是的。如果您将用户 ID 和登录信息存储在 cookie 中,是什么阻止了某人将其 cookie 更改为任何人的用户 ID 和登录信息?
您需要设置身份验证票证系统。基本上它是一个 cookie 值,当没有会话存在时会被检查。如果存在值,则针对应包含其用户 ID 的票证表运行该值。如果您找到票,请给他们一个会话和一张新票。
【讨论】:
嗯...当用户根据他们的身份验证 cookie 重新验证浏览器时,我确信 ASP.Net 已经在重新签发新票。但是,我相信您还建议即使存储在用户数据中的加密用户 ID 也可能被恶意用户自己的身份验证 cookie 中存储的加密数据所取代?但是我不确定我是否完全遵循 auth cookie 中 userdata 部分的观点!【参考方案4】:如果您已经有一个包含个人资料信息的用户表,为什么不使用custom profile provider 挂钩。
如果您想了解如何实现此类功能的另一个示例,可以查看SQL Table Profile Provider
【讨论】:
【参考方案5】:也许你可以创建另一个 cookie...我个人不会弄乱 auth cookie。
【讨论】:
实际上我正在生成一个新的 auth cookie。我可以继续在新 cookie 的 UserData 部分中存储一个简单的文本字符串。我的问题是关于序列化更复杂的对象。 我的意思是除了 auth cookie 之外的一个 cookie。保留身份验证 cookie 并为临时用户数据创建一个新的未加密 cookie。 不,我会存储用户 ID 和昵称 - 不希望在没有加密的情况下存储此类敏感数据 通过将信息存储在 auth cookie 中提供的加密是不够的。如果您认为此信息“敏感”,请不要将其存储在 cookie 中。【参考方案6】:在 cookie 中存储额外的用户数据意味着每个请求都会从客户端来回发送一个更大的 cookie。
避免您担心的额外数据库命中的更好方法是在用户登录后将该数据缓存在内存中。
ASP.NET 有一个每个请求的缓存 HttpContext.Current.Items 和一个应用程序域缓存 HttpContext.Current.Cache,我认为您正在寻找 HttpContext.Current.Cache 在这个实例中。
或者,如果您需要跨 Web 服务器(负载平衡的 Web 服务器)进行缓存,您可以查看第 3 方键值存储,例如 memcached、redis、velocity、ncache 等。
【讨论】:
这与会话变量有何不同以上是关于ASP.Net 将用户数据存储在 Auth Cookie 中的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Web 窗体用户数据 - 未存储在 SQL 中
ASP.NET SignalR - 无法将存储在数据库中的消息列表发送给用户