登录后刷新AntiForgeryToken [英] Reload AntiForgeryToken after a login

查看:473
本文介绍了登录后刷新AntiForgeryToken的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在位于景色的形式来重载AntiForgeryToken,在同一页面另一种观点认为一个全成登录后。

I need to reload an AntiForgeryToken in a form located in a view, after a successfull login in another view in the same page.

我可以输入@ Html.AntiForgeryToken形式的更新()键?

Can I make an update in the form input @Html.AntiForgeryToken() key with the new one from the result login page via jQuery?

如果是,则该recomended和安全性?

If yes, is this recomended and secure?

我该怎么办呢?

编辑:

在布局我有diferent PartialViews:

In the Layout I have diferent PartialViews:

该部分登入:

<ul class="menudrt" id="headerLogin">
    @{ Html.RenderAction(MVC.Account.LoginHeader()); }
</ul>

和在另一部分,则hability送评论:

And in another Partial, the hability to send a comment:

<div class="comentsform">

    <!-- Comments form -->
    @{ Html.RenderAction(MVC.Comment.Create()); }

</div>

要发送评论,用户必须先登录,所以登录后,评论需要更新AntiForgeryToken或者我得到验证错误,因为它现在登录已经取得diferent。

To send a comment, the user have to login, so after login, the comment form needs to update the AntiForgeryToken or I get the validation error because it's diferent now that the login has been made.

感谢

推荐答案

该问题发生,因为防伪标记包含当前已验证用户的用户名。

The issue is occurring because the AntiForgery token contains the username of the currently authenticated user.

因此​​,这里发生了什么:

So here's what happens:


  1. 匿名用户浏览到您的网页

  2. 是评论表单生成一个防伪标记,但此令牌包含一个空的用户名(因为在那一刻的用户是匿名的)

  3. 您正在使用AJAX调用登录

  4. 用户提交评论表单到服务器,因为在初次令牌空的用户名是比当前认证的用户名不同的令牌验证失败。

所以,你有几个选项来解决这个问题:

So you have a couple of options to fix this issue:


  1. 在第3步中不使用AJAX调用。使用标准表单提交登录用户,并重定向他回到最初请求的页面。当然,评论表单将重新加载,并为其生成正确​​的防伪标记。

  2. 刷新防伪标记测井在
  3. 之后

解决方案1.显而易见并没有使它成为一个很好的候选用于覆盖在我的答案。让我们来看看第二个解决方案如何实施。

The obviousness of solution 1. doesn't make it a good candidate for covering it in my answer. Let's see how the second solution could be implemented.

但是,首先让我们来重现问题用一个例子:

But first let's reproduce the problem with an example:

控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        return View();
    }

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Login()
    {
        FormsAuthentication.SetAuthCookie("john", false);
        return Json(new { success = true });
    }

    [HttpPost]
    [ValidateAntiForgeryToken()]
    public ActionResult Comment()
    {
        return Content("Thanks for commenting");
    }
}

〜/查看/主页/ Index.cshtml

<div>
    @{ Html.RenderPartial("_Login"); }
</div>

<div id="comment">
    @{ Html.RenderPartial("_Comment"); }
</div>

<script type="text/javascript">
    $('#loginForm').submit(function () {
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                alert('You are now successfully logged in');
            }
        });
        return false;
    });
</script>

〜/查看/主页/ _Login.cshtml

@using (Html.BeginForm("Login", null, FormMethod.Post, new { id = "loginForm" }))
{
    @Html.AntiForgeryToken()
    <button type="submit">Login</button>
}

〜/查看/主页/ _Comment.cshtml

@using (Html.BeginForm("Comment", null, FormMethod.Post))
{ 
    @Html.AntiForgeryToken()
    <button type="submit">Comment</button>
}

好吧,现在当您导航到主/指数对应的视图将呈现,如果你的评论按钮preSS没有记录,在首先它会工作。但是,如果您登录,然后评论将失败。

Alright now when you navigate to the Home/Index the corresponding view will be rendered and if you press on the Comment button without logging-in first it will work. But if you login and then Comment it will fail.

因此​​,我们可以添加另一个控制器动作,将在以产生新的令牌返回一个简单的 Html.AntiForgeryToken 调用局部视图:

So we could add another controller action that will return a partial view with a simple Html.AntiForgeryToken call in order to generate a fresh token:

public ActionResult RefreshToken()
{
    return PartialView("_AntiForgeryToken");
}

和相应的部分(〜/查看/主页/ _AntiForgeryToken.cshtml

@Html.AntiForgeryToken()

和最后一步是通过更新我们的AJAX调用刷新令牌:

And the final step is to refresh the token by updating our AJAX call:

<script type="text/javascript">
    $('#loginForm').submit(function () {
        $.ajax({
            url: this.action,
            type: this.method,
            data: $(this).serialize(),
            success: function (result) {
                $.get('@Url.Action("RefreshToken")', function (html) {
                    var tokenValue = $('<div />').html(html).find('input[type="hidden"]').val();
                    $('#comment input[type="hidden"]').val(tokenValue);
                    alert('You are now successfully logged in and can comment');
                });
            }
        });
        return false;
    });
</script>

这篇关于登录后刷新AntiForgeryToken的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆