带有 ViewModel 和两个表单的页面上的“防伪 cookie 令牌和表单字段令牌不匹配”
Posted
技术标签:
【中文标题】带有 ViewModel 和两个表单的页面上的“防伪 cookie 令牌和表单字段令牌不匹配”【英文标题】:"The anti-forgery cookie token and form field token do not match" on page with ViewModel and two forms 【发布时间】:2015-06-17 23:20:25 【问题描述】:在 Mono 上运行的 MVC4 应用程序中出现错误:
防伪cookie令牌和表单字段令牌不匹配
在“登录和注册”页面上。此页面有一个LoginOrRegisterViewModel
,如下所示:
public class LoginOrRegisterViewModel
public LoginModel Login get; set;
public RegisterModel Register get; set;
通过 GET 请求传递到页面。
页面上有两个html.BeginForms()
,一个Login
-form 和一个Register
-form。第一个调用控制器上的Login
操作,第二个调用Register
操作。这两个操作都有一个ValidateAntiForgeryToken
属性。提交表单时,分别从LoginOrRegisterViewModel
获取Login
或Register
。
当页面加载并且注册用户在一段时间(几个小时?)后尝试登录时,最初显示“登录和注册”页面,但是当提交Login
表单时,上面的错误会一直显示到根页面已刷新。
我在 Web.config 中包含了一个机器密钥,并在两个表单中都添加了 Html.AntiForgeryToken()
。我怀疑这个错误可能与两个表单和视图模型有关。
有谁知道如何解决这个错误?谢谢。
【问题讨论】:
您是否同时使用 Code First 重新播种数据库而忘记将其关闭或其他什么?这是在数据库中重新创建用户的典型情况,从而导致防伪令牌有所不同。 @WimOmbelets 否,数据库未重新植入。只有在注册用户时才创建(显然)。 调用者会话在这几个小时内是否过期? AFAIK 这些令牌存储在会话中... :) @dna 这有关系吗?这些类型的应用程序错误不利于用户体验。现在我刚刚删除了防伪令牌。 好吧,如果会话过期(其中包含防伪令牌),那么当用户在此之后发布表单时,令牌的验证显然会失败。我并不是说这是您错误的原因,但它可能值得研究。 【参考方案1】:MVC 最佳编码标准,始终以代码关注点分离的方式进行实践。
创建两个不同的模型 1 用于 LoginViewModel 和 2 用于注册视图模型。 通过 Partial 或 RenderAction 关键字为登录和注册和访问创建单独的局部视图。如果您将 @Html.AntiForgeryToken() 放在您的 html 表单上,那么您需要通过编写属性 [ValidateAntiForgeryToken()] 在控制器端方法上验证反伪造 .
Html 助手将在您的表单中生成唯一标记,例如,
<input name="__RequestVerificationToken" type="hidden" value="4dvPVQIvpXNEKZyV1DCjeN1rmtMDJ9fQ2">
将为每个表单生成唯一的防伪令牌,并解决您的冲突。
如果您仍然面临困难,请告诉我。
【讨论】:
以上是关于带有 ViewModel 和两个表单的页面上的“防伪 cookie 令牌和表单字段令牌不匹配”的主要内容,如果未能解决你的问题,请参考以下文章
如何将相同的viewmodel设置为xamarin表单中的新mvvm中的两个视图
如何将流从 ViewModel 发送到 XAML 页面上的 MediaElement?