asp.net mvc - jQuery অ্যাজাক্স কল এবং Html.AnttiForgeryToken()




asp.net-mvc ajax (13)

আমি আমার অ্যাপে ইন্টারনেটের চারপাশে কিছু ব্লগ পোস্টে পড়েছি এমন তথ্যগুলি অনুসরণ করে সিএসআরএফ আক্রমণের ক্ষয়ক্ষতি প্রয়োগ করেছি। বিশেষ করে এই পোস্ট আমার বাস্তবায়ন ড্রাইভার হয়েছে

মূলত সেই নিবন্ধগুলি এবং সুপারিশগুলি যে সিএসআরএফ আক্রমণ প্রতিরোধ করতে পারে তার জন্য নিম্নলিখিত কোডটি প্রয়োগ করা উচিত:

1) POST Http ক্রিয়াটি স্বীকার করে এমন প্রতিটি পদক্ষেপে [ValidateAntiForgeryToken] করুন

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult SomeAction( SomeModel model ) {
}

2) সার্ভারে ডেটা জমা দেওয়ার ফর্মগুলির মধ্যে <%= Html.AntiForgeryToken() %> সহায়ক যোগ করুন

<div style="text-align:right; padding: 8px;">
    <%= Html.AntiForgeryToken() %>
    <input type="submit" id="btnSave" value="Save" />
</div>

যাইহোক আমার অ্যাপ্লিকেশনের কিছু অংশে আমি কোনও ফর্ম না থাকলে সার্ভারে jQuery এর সাথে Ajax পোস্টগুলি করছি। এটি উদাহরণস্বরূপ ঘটে যেখানে আমি কোনও নির্দিষ্ট পদক্ষেপের জন্য ব্যবহারকারীকে একটি চিত্রতে ক্লিক করার অনুমতি দিচ্ছি।

ধরুন আমার ক্রিয়াকলাপের তালিকার একটি টেবিল আছে। আমার টেবিলে একটি কলামে একটি চিত্র রয়েছে যা বলে "সমাপ্তি হিসাবে ক্রিয়াকলাপকে চিহ্নিত করুন" এবং যখন ব্যবহারকারী সেই ক্রিয়াকলাপটিতে ক্লিক করে তখন আমি নিম্নরূপ নমুনা হিসাবে Ajax POST করছি:

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: {},
        success: function (response) {
            // ....
        }
    });
});

আমি কিভাবে এই ক্ষেত্রে <%= Html.AntiForgeryToken() %> ব্যবহার করতে পারি? আমি কি অ্যাজ্যাক্স কলের ডাটা প্যারামিটারের ভিতরে সাহায্যকারী কলটি অন্তর্ভুক্ত করব?

দীর্ঘ পোস্টের জন্য দুঃখিত এবং সাহায্য করার জন্য অনেক ধন্যবাদ

সম্পাদনা করুন :

jayrdub উত্তর অনুসারে আমি নিম্নলিখিত পদ্ধতিতে ব্যবহার করেছি

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: {
            AddAntiForgeryToken({}),
            id: parseInt($(this).attr("title"))
        },
        success: function (response) {
            // ....
        }
    });
});

প্রথমে এইচটিএমএল @ এন্টিফোর্রি টোকেন () এ এইচটিএমএল ব্যবহার করুন

 $.ajax({
        url: "@Url.Action("SomeMethod", "SomeController")",
        type: 'POST',
        data: JSON.stringify(jsonObject),
        contentType: 'application/json; charset=utf-8',
        dataType: 'json',
        async: false,
        beforeSend: function (request) {
            request.setRequestHeader("RequestVerificationToken", $("[name='__RequestVerificationToken']").val());
        },
        success: function (msg) {
            alert(msg);
        }

360Airwalk সমাধান সামান্য উন্নতি। এটি জাভাস্ক্রিপ্ট ফাংশনের মধ্যে এন্টি ফোর্গ্রি টোকেনকে আবদ্ধ করে, তাই @ Html.AnttiForgeryToken () কে আর প্রতিটি দর্শনে অন্তর্ভুক্ত করতে হবে না।

$(document).ready(function () {
    var securityToken = $('@Html.AntiForgeryToken()').attr('value');
    $('body').bind('ajaxSend', function (elm, xhr, s) {
        if (s.type == 'POST' && typeof securityToken != 'undefined') {
            if (s.data.length > 0) {
                s.data += "&__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
            else {
                s.data = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
            }
        }
    });
});

AntiforgeryToken এখনও একটি ব্যথা, উপরে উদাহরণের কেউ আমার জন্য শব্দ কাজ শব্দ। সেখানে অনেক আছে। তাই আমি তাদের সব মিলিত। একটি @ Html.Antiforgery প্রয়োজন আইআরসি কাছাকাছি ঝুলন্ত একটি ফর্ম টোকেন

তাই সমাধান:

function Forgizzle(eggs) {
    eggs.__RequestVerificationToken =  $($("input[name=__RequestVerificationToken]")[0]).val();
    return eggs;
}

$.ajax({
            url: url,
            type: 'post',
            data: Forgizzle({ id: id, sweets: milkway }),
});

সন্দেহ হলে, আরো $ লক্ষণ যোগ করুন


আপনি এটিও করতে পারেন:

$("a.markAsDone").click(function (event) {
    event.preventDefault();

    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: $('<form>@Html.AntiForgeryToken()</form>').serialize(),
        success: function (response) {
        // ....
        }
    });
});

এটি Razor ব্যবহার করছে, কিন্তু আপনি যদি WebForms সিনট্যাক্স ব্যবহার করেন তবে আপনি <%= %> ট্যাগগুলি ব্যবহার করতে পারেন


আমি আপনাকে যা করতে হবে তা নিশ্চিত করুন যে POST অনুরোধে "__RequestVerificationToken" ইনপুট অন্তর্ভুক্ত করা হয়েছে। তথ্যটির অর্ধেক অংশ (অর্থাৎ ব্যবহারকারীর কুকিতে টোকেন) ইতিমধ্যে একটি AJAX POST অনুরোধের মাধ্যমে স্বয়ংক্রিয়ভাবে পাঠানো হয়েছে।

যেমন,

$("a.markAsDone").click(function (event) {
    event.preventDefault();
    $.ajax({
        type: "post",
        dataType: "html",
        url: $(this).attr("rel"),
        data: { 
            "__RequestVerificationToken":
            $("input[name=__RequestVerificationToken]").val() 
        },
        success: function (response) {
            // ....
        }
    });
});

আমি এই মত একটি সহজ জেএস ফাংশন ব্যবহার করুন

AddAntiForgeryToken = function(data) {
    data.__RequestVerificationToken = $('#__AjaxAntiForgeryForm input[name=__RequestVerificationToken]').val();
    return data;
};

যেহেতু একটি পৃষ্ঠার প্রতিটি ফর্মটিতে টোকেনটির জন্য একই মান থাকবে, তাই আপনার শীর্ষ-সর্বাধিক মাস্টার পৃষ্ঠায় এটির মতো কিছু রাখুন

<%-- used for ajax in AddAntiForgeryToken() --%>
<form id="__AjaxAntiForgeryForm" action="#" method="post"><%= Html.AntiForgeryToken()%></form>  

তারপর আপনার AJAX কল করুন (আপনার দ্বিতীয় উদাহরণ মেলে সম্পাদনা)

$.ajax({
    type: "post",
    dataType: "html",
    url: $(this).attr("rel"),
    data: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
    success: function (response) {
        // ....
    }
});

আমি এখানে একটি উন্নত necromancer মত মনে হয়, কিন্তু এটি এখনও 4 বছর পরে MVC5 একটি সমস্যা।

AJAX অনুরোধগুলি সঠিকভাবে হ্যান্ডেল করতে অ্যান্টি-জালিয়াতি টোকেনকে অজ্যাক্স কলগুলিতে সার্ভারে প্রেরণ করতে হবে। আপনার পোস্ট তথ্য এবং মডেলের মধ্যে এটি সংহত করা নোংরা এবং অপ্রয়োজনীয়। কাস্টম শিরোনাম হিসাবে টোকেন যোগ করা হল পরিষ্কার এবং পুনঃব্যবহারযোগ্য - এবং আপনি এটি কনফিগার করতে পারেন যাতে আপনাকে এটি প্রতিবার মনে রাখতে হবে না।

একটি ব্যতিক্রম আছে - অবাধ্য অজ্যাক অজ্যাক্স কলগুলির জন্য বিশেষ চিকিত্সার প্রয়োজন নেই। টোকেন নিয়মিত লুকানো ইনপুট ক্ষেত্রে স্বাভাবিক হিসাবে পাস করা হয়। একটি নিয়মিত পোস্ট হিসাবে ঠিক একই।

_Layout.cshtml

_Layout.cshtml আমি এই জাভাস্ক্রিপ্ট ব্লক আছে। এটি DOM- এ টোকেনটি লিখছে না, বরং এটি MVC Helper জেনারেট করা লুকানো ইনপুট আক্ষরিক থেকে এটি বের করতে jQuery ব্যবহার করে। শিরোনাম নাম যা যাদু স্ট্রিং বৈশিষ্ট্য শ্রেণীতে ধ্রুবক হিসাবে সংজ্ঞায়িত করা হয়।

<script type="text/javascript">
    $(document).ready(function () {
        var isAbsoluteURI = new RegExp('^(?:[a-z]+:)?//', 'i');
        //http://.com/questions/10687099/how-to-test-if-a-url-string-is-absolute-or-relative

        $.ajaxSetup({
            beforeSend: function (xhr) {
                if (!isAbsoluteURI.test(this.url)) {
                    //only add header to relative URLs
                    xhr.setRequestHeader(
                       '@.ValidateAntiForgeryTokenOnAllPosts.HTTP_HEADER_NAME', 
                       $('@Html.AntiForgeryToken()').val()
                    );
                }
            }
        });
    });
</script>

পূর্বে প্রেরণ ফাংশনে একক উদ্ধৃতি ব্যবহার করে নোট করুন - রুপান্তরিত ইনপুট উপাদানটি দ্বি উদ্ধৃতি ব্যবহার করে যা জাভাস্ক্রিপ্ট আক্ষরিককে ভাঙ্গবে।

ক্লায়েন্ট জাভাস্ক্রিপ্ট

যখন এটি কার্যকর করা হয় উপরের স্যান্ডউন্ড ফাংশনটি বলা হয় এবং AntiForgeryToken স্বয়ংক্রিয়ভাবে অনুরোধ শিরোনামগুলিতে যোগ করা হয়।

$.ajax({
  type: "POST",
  url: "CSRFProtectedMethod",
  dataType: "json",
  contentType: "application/json; charset=utf-8",
  success: function (data) {
    //victory
  }
});

সার্ভার লাইব্রেরি

একটি কাস্টম বৈশিষ্ট্য অ মানক টোকেন প্রক্রিয়া প্রয়োজন। এটি @ viggity এর সমাধানটি তৈরি করে তবে অযৌক্তিক AJAX সঠিকভাবে পরিচালনা করে। এই কোড আপনার সাধারণ লাইব্রেরিতে দূরে tucked করা যাবে

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ValidateAntiForgeryTokenOnAllPosts : AuthorizeAttribute
{
    public const string HTTP_HEADER_NAME = "x-RequestVerificationToken";

    public override void OnAuthorization(AuthorizationContext filterContext)
    {
        var request = filterContext.HttpContext.Request;

        //  Only validate POSTs
        if (request.HttpMethod == WebRequestMethods.Http.Post)
        {

            var headerTokenValue = request.Headers[HTTP_HEADER_NAME];

            // Ajax POSTs using jquery have a header set that defines the token.
            // However using unobtrusive ajax the token is still submitted normally in the form.
            // if the header is present then use it, else fall back to processing the form like normal
            if (headerTokenValue != null)
            {
                var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];

                var cookieValue = antiForgeryCookie != null
                    ? antiForgeryCookie.Value
                    : null;

                AntiForgery.Validate(cookieValue, headerTokenValue);
            }
            else
            {
                new ValidateAntiForgeryTokenAttribute()
                    .OnAuthorization(filterContext);
            }
        }
    }
}

সার্ভার / কন্ট্রোলার

এখন আপনি শুধু আপনার অ্যাকশন এ বৈশিষ্ট্য প্রয়োগ করুন। এমনকি ভাল আপনি আপনার নিয়ামক এট্রিবিউট প্রয়োগ করতে পারেন এবং সব অনুরোধ বৈধ হবে।

[HttpPost]
[ValidateAntiForgeryTokenOnAllPosts]
public virtual ActionResult CSRFProtectedMethod()
{
  return Json(true, JsonRequestBehavior.DenyGet);
}

আমি জানি অন্য অনেক উত্তর আছে, কিন্তু এই নিবন্ধটি চমৎকার এবং সংক্ষেপে এবং আপনাকে আপনার সমস্ত HttpPosts চেক করতে বাধ্য করে, কেবল তাদের মধ্যে কিছু নয়:

http://richiban.wordpress.com/2013/02/06/validating-net-mvc-4-anti-forgery-tokens-in-ajax-requests/

এটি ফর্ম সংগ্রহ সংশোধন করার চেষ্টা করার পরিবর্তে HTTP হেডার ব্যবহার করে।

সার্ভার

//make sure to add this to your global action filters
[AttributeUsage(AttributeTargets.Class)]
public class ValidateAntiForgeryTokenOnAllPosts : AuthorizeAttribute
{
    public override void OnAuthorization( AuthorizationContext filterContext )
    {
        var request = filterContext.HttpContext.Request;

        //  Only validate POSTs
        if (request.HttpMethod == WebRequestMethods.Http.Post)
        {
            //  Ajax POSTs and normal form posts have to be treated differently when it comes
            //  to validating the AntiForgeryToken
            if (request.IsAjaxRequest())
            {
                var antiForgeryCookie = request.Cookies[AntiForgeryConfig.CookieName];

                var cookieValue = antiForgeryCookie != null
                    ? antiForgeryCookie.Value 
                    : null;

                AntiForgery.Validate(cookieValue, request.Headers["__RequestVerificationToken"]);
            }
            else
            {
                new ValidateAntiForgeryTokenAttribute()
                    .OnAuthorization(filterContext);
            }
        }
    }
}

মক্কেল

var token = $('[name=__RequestVerificationToken]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;

$.ajax({
    type: 'POST',
    url: '/Home/Ajax',
    cache: false,
    headers: headers,
    contentType: 'application/json; charset=utf-8',
    data: { title: "This is my title", contents: "These are my contents" },
    success: function () {
        ...
    },
    error: function () {
        ...
    }
});

আমি সচেতন যে এই প্রশ্নটি পোস্ট করার পরে এটি কিছু সময় হয়েছে, কিন্তু আমি সত্যিই দরকারী সংস্থান খুঁজে পেয়েছি, যা এন্টোফোর্রি টোকেন ব্যবহার সম্পর্কে আলোচনা করে এবং এটি ব্যবহারের জন্য কম বিরক্তিকর করে তোলে। এটি AJAX কলগুলিতে সহজেই Antiforgery টোকেনসহ jQuery প্লাগইন সরবরাহ করে:

এএসপি.নেট এমভিসি এবং এজেএক্সের জন্য এন্টি ফোর্গ্রি অনুরোধের রেসিপি

আমি অনেক অবদান করছি না, কিন্তু হয়তো কেউ এটি দরকারী খুঁজে পাবেন।


এখানে আমি দেখেছি সবচেয়ে সহজ উপায়। দ্রষ্টব্য: আপনার ভিউতে "@ Html.AntiForgeryToken ()" আছে তা নিশ্চিত করুন

  $("a.markAsDone").click(function (event) {
        event.preventDefault();
        var sToken = document.getElementsByName("__RequestVerificationToken")[0].value;
        $.ajax({
            url: $(this).attr("rel"),
            type: "POST",
            contentType: "application/x-www-form-urlencoded",
            data: { '__RequestVerificationToken': sToken, 'id': parseInt($(this).attr("title")) }
        })
        .done(function (data) {
            //Process MVC Data here
        })
        .fail(function (jqXHR, textStatus, errorThrown) {
            //Process Failure here
        });
    });

প্রতিটি $ এর জন্য https://gist.github.com/scottrippey/3428114 থেকে এই খুব চতুর ধারণাটি খুঁজে পেয়েছেন .জ্যাক্স কল এটি অনুরোধটি সংশোধন করে এবং টোকেন যোগ করে।

// Setup CSRF safety for AJAX:
$.ajaxPrefilter(function(options, originalOptions, jqXHR) {
    if (options.type.toUpperCase() === "POST") {
        // We need to add the verificationToken to all POSTs
        var token = $("input[name^=__RequestVerificationToken]").first();
        if (!token.length) return;

        var tokenName = token.attr("name");

        // If the data is JSON, then we need to put the token in the QueryString:
        if (options.contentType.indexOf('application/json') === 0) {
            // Add the token to the URL, because we can't add it to the JSON data:
            options.url += ((options.url.indexOf("?") === -1) ? "?" : "&") + token.serialize();
        } else if (typeof options.data === 'string' && options.data.indexOf(tokenName) === -1) {
            // Append to the data string:
            options.data += (options.data ? "&" : "") + token.serialize();
        }
    }
});

1. সার্ভার থেকে টোকেন পেতে ডিফাইন ফাংশন

@function
{

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

2. সার্ভার পাঠানোর আগে টোকেন এবং সেট হেডার পান

var token = '@TokenHeaderValue()';    

       $http({
           method: "POST",
           url: './MainBackend/MessageDelete',
           data: dataSend,
           headers: {
               'RequestVerificationToken': token
           }
       }).success(function (data) {
           alert(data)
       });

3. HttpRequestBase এ অন্সেসার বৈধতা আপনি পোস্ট / পেতে হ্যান্ডেল পদ্ধতি

        string cookieToken = "";
        string formToken = "";
        string[] tokens = Request.Headers["RequestVerificationToken"].Split(':');
            if (tokens.Length == 2)
            {
                cookieToken = tokens[0].Trim();
                formToken = tokens[1].Trim();
            }
        AntiForgery.Validate(cookieToken, formToken);

function DeletePersonel(id) {

    var data = new FormData();
    data.append("__RequestVerificationToken", "@HtmlHelper.GetAntiForgeryToken()");

    $.ajax({
        type: 'POST',
        url: '/Personel/Delete/' + id,
        data: data,
        cache: false,
        processData: false,
        contentType: false,
        success: function (result) {
        }
    });
}

public static class HtmlHelper {
    public static string GetAntiForgeryToken() {
        System.Text.RegularExpressions.Match value = 
                System.Text.RegularExpressions.Regex.Match(System.Web.Helpers.AntiForgery.GetHtml().ToString(), 
                        "(?:value=\")(.*)(?:\")");
        if (value.Success) {
            return value.Groups[1].Value;
        }
        return "";
    }
}




antiforgerytoken