在我们开发的电子商务解决方案中,我们使用的是AspNet Identity 2.2.1,并且要求任何访客(匿名)用户在未事先注册网站的情况下完成结账。为了满足这个要求,编写了一个名为UserMigrationAttribute的ActionFilter,它从cookie获取SessionTrackId(字符串GUID) - 如果没有找到SessionTrackId,我们从每个请求为HttpModule设置请求cookie-并在数据库中创建和实际的IdentityUser用户名像SessionTrackId@mydomain.com。
我们使用此UserMigration属性修饰了BaseController类,以便在整个站点中使用其功能。
到目前为止,一切都按预期工作,单个下行问题,即当我们第一次为任何用户加载页面时,如果我们尝试对具有{{1}的方法进行Jquery Ajax调用}}属性,即使我们在每个ajax调用中发送[ValidateAntiForgeryToken]
参数,调用也会因“The provided anti-forgery token was meant for a different claims-based user than the current user.
”错误而失败。
但是如果用户通过单击链接打开另一个页面和/或重新加载/刷新当前页面,则所有后续的ajax调用都会成功完成。
在我们的理解中,UserMigrationAttribute在OnActionExecuting方法上创建用户,但是在我们签署用户的过程中@Html.AntiForgeryToken()没有使用正确的值进行更新。
您可以在下面找到UserMigrationAttribute代码;
__RequestVerificationToken
非常感谢任何帮助或建议。
谢谢,
答案 0 :(得分:2)
这种情况正在发生,因为防伪令牌是在cookie中设置的,在下一次请求之前不会更新。如果您手动为用户签名,您还应该发出重定向(即使是他们已经前往的同一页面),只是为了确保cookie数据正确。这通常是自然发生的,因为登录表单将重定向到用户登录后需要授权的URL,从而否定问题。由于您当前未重定向,因此数据不同步。
但是,我不得不说这对于这个特定的用例来说似乎是一个非常糟糕的解决方案。创建某种临时类型的用户并签署该用户以处理访客结帐会在数据库中创建不必要的无用数据,最多会导致错误和其他问题,例如您遇到的问题,最糟糕的情况
我还经营一个电子商务网站,我们处理客人结账的方式非常简单。结账数据仅存储在会话中(电子邮件,发货/账单地址等)。我们构建一个视图模型来处理实际结账,其中提交销售所需的数据来自用户对象,如果他们已经登录,或者这些会话变量(如果他们不是)。如果用户既没有登录,也没有设置必要的会话变量,那么它们将被重定向到正在收集账单/运送等的入职表单。
对于维护匿名购物车等其他方面,我们使用带有购物车标识符的永久cookie。如果用户最终创建了一个帐户,我们会将匿名购物车与其用户相关联,然后删除该Cookie。这可以确保他们的购物车能够在会话超时后继续存在,例如关闭浏览器,即使他们是匿名的。
换句话说,在所有这些事情中,实际上不需要用户对象。如果它(用户已登录),那么很好,我们将使用它。否则,我们会通过其他方式收集并保留必要的结账信息。