11

ホットタオルSPA申し込みの登録とログインを設定しようとしています。asp.net シングル ページ アプリケーション テンプレートに基づいて、SimpleMembershipFilters と ValidateHttpAntiForgeryTokenAttribute を作成しました。

どのように取得しますか

 @Html.AntiForgeryToken()

Durandal SPA パターンで動作するコード。

現在、私はregister.htmlを持っています

<section>
    <h2 data-bind="text: title"></h2>

    <label>Firstname:</label><input data-bind="value: firstName" type="text"  />
    <label>Lastname:</label><input data-bind="value: lastName" type="text"  />
    <label>Email:</label><input data-bind="value: emailAddress" type="text"  />
    <label>Company:</label><input data-bind="value: company" type="text"  />
    <br />
    <label>Password:</label><input data-bind="value: password1" type="password" />
    <label>Re-Enter Password:</label><input data-bind="value: password2" type="password" />
    <input type="button" value="Register" data-bind="click: registerUser" class="btn" />
</section>

register.js :

define(['services/logger'], function (logger) {
    var vm = {
        activate: activate,
        title: 'Register',
        firstName: ko.observable(),
        lastName: ko.observable(),
        emailAddress: ko.observable(),
        company: ko.observable(),
        password1: ko.observable(),
        password2: ko.observable(),
        registerUser: function () {
            var d = {
                'FirstName': vm.firstName,
                'LastName': vm.lastName,
                'EmailAddress': vm.emailAddress,
                'Company': vm.company,
                'Password': vm.password1,
                'ConfirmPassword': vm.password2
            };
            $.ajax({
                url: 'Account/JsonRegister',
                type: "POST",
                data: d ,
                success: function (result) {
                },
                error: function (result) {
                }
            });
        },
    };


    return vm;

    //#region Internal Methods
    function activate() {
        logger.log('Login Screen Activated', null, 'login', true);
        return true;
    }
    //#endregion
});

$ajax 呼び出しで、AntiForgeryToken を渡すにはどうすればよいですか? また、トークンを作成するにはどうすればよいですか?

4

4 に答える 4

7

JavaScript を使用して偽造防止トークンを使用する方法については、この記事をお読みください。この記事は WebApi 向けに書かれていますが、必要に応じて MVC コントローラーに簡単に適用できます。

短い答えは次のようなものです: cshtml ビュー内:

<script>
    @functions{
        public string TokenHeaderValue()
        {
            string cookieToken, formToken;
            AntiForgery.GetTokens(null, out cookieToken, out formToken);
            return cookieToken + ":" + formToken;                
        }
    }

    $.ajax("api/values", {
        type: "post",
        contentType: "application/json",
        data: {  }, // JSON data goes here
        dataType: "json",
        headers: {
            'RequestVerificationToken': '@TokenHeaderValue()'
        }
    });
</script>

次に、asp.net コントローラー内で、次のようにトークンを検証する必要があります。

void ValidateRequestHeader(HttpRequestMessage request)
{
    string cookieToken = "";
    string formToken = "";

    IEnumerable<string> tokenHeaders;
    if (request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
    {
        string[] tokens = tokenHeaders.First().Split(':');
        if (tokens.Length == 2)
        {
            cookieToken = tokens[0].Trim();
            formToken = tokens[1].Trim();
        }
    }
    AntiForgery.Validate(cookieToken, formToken);
}

ヘッダーに渡す理由は、リクエストのクエリ文字列または本文内の ajax 呼び出しでパラメーター データ パラメーターとして渡す場合です。そうなると、さまざまなシナリオすべてで偽造防止トークンを取得するのが難しくなります。本体を逆シリアル化してからトークンを見つける必要があるためです。ヘッダーでは、かなり一貫性があり、取得が簡単です。


**光線の編集

以下は、偽造防止トークンが提供されているかどうかを検証する Web API メソッドに属性を付けるために使用できるアクション フィルターの例です。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Helpers;
using System.Web.Http.Filters;
using System.Net.Http;
using System.Net;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Threading;

namespace PAWS.Web.Classes.Filters
{
    public class ValidateJsonAntiForgeryTokenAttribute : FilterAttribute, IAuthorizationFilter
    {
        public Task<HttpResponseMessage> ExecuteAuthorizationFilterAsync(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            if (actionContext == null)
            {
                throw new ArgumentNullException("HttpActionContext");
            }

            if (actionContext.Request.Method != HttpMethod.Get)
            {
                return ValidateAntiForgeryToken(actionContext, cancellationToken, continuation);
            }

            return continuation();
        }

        private Task<HttpResponseMessage> FromResult(HttpResponseMessage result)
        {
            var source = new TaskCompletionSource<HttpResponseMessage>();
            source.SetResult(result);
            return source.Task;
        }

        private Task<HttpResponseMessage> ValidateAntiForgeryToken(HttpActionContext actionContext, CancellationToken cancellationToken, Func<Task<HttpResponseMessage>> continuation)
        {
            try
            {
                string cookieToken = "";
                string formToken = "";
                IEnumerable<string> tokenHeaders;
                if (actionContext.Request.Headers.TryGetValues("RequestVerificationToken", out tokenHeaders))
                {
                    string[] tokens = tokenHeaders.First().Split(':');
                    if (tokens.Length == 2)
                    {
                        cookieToken = tokens[0].Trim();
                        formToken = tokens[1].Trim();
                    }
                }
                AntiForgery.Validate(cookieToken, formToken);
            }
            catch (System.Web.Mvc.HttpAntiForgeryException ex)
            {
                actionContext.Response = new HttpResponseMessage
                {
                    StatusCode = HttpStatusCode.Forbidden,
                    RequestMessage = actionContext.ControllerContext.Request
                };
                return FromResult(actionContext.Response);
            }
            return continuation();
        }
    }
}
于 2013-03-19T23:13:38.967 に答える
3

JS var でトークンの値を取得する

var antiForgeryToken = $('input[name="__RequestVerificationToken"]').val();

次に、 .ajax呼び出しのbeforeSend関数でajax POST ヘッダーに追加するだけです。

beforeSend: function (xhr, settings) {
            if (settings.data != "") {
                settings.data += '&';
            }
            settings.data += '__RequestVerificationToken=' +  encodeURIComponent(antiForgeryToken);
}
于 2013-03-14T17:42:29.510 に答える