অ্যাজএফ পোস্ট এএসপি.নেট এমভিসি-তে অ্যান্টিফোর্জিটেকেন অন্তর্ভুক্ত করুন


167

অজ্যাক্স সহ অ্যান্টিফোরজি টোকেন নিয়ে আমার সমস্যা হচ্ছে। আমি এএসপি.নেট এমভিসি ৩ ব্যবহার করছি I আমি jQuery আজাক্স কল এবং এইচটিএমএল.আন্টিফোরজিটোকেন () এ সমাধানটি চেষ্টা করেছি । সেই সমাধানটি ব্যবহার করে, টোকেনটি এখন পাস করা হচ্ছে:

var data = { ... } // with token, key is '__RequestVerificationToken'

$.ajax({
        type: "POST",
        data: data,
        datatype: "json",
        traditional: true,
        contentType: "application/json; charset=utf-8",
        url: myURL,
        success: function (response) {
            ...
        },
        error: function (response) {
            ...
        }
    });

আমি যখন [ValidateAntiForgeryToken]ডেটা (টোকেন সহ) নিয়ন্ত্রকের কাছে পরামিতি হিসাবে প্রেরণ করা হচ্ছে তা দেখার জন্য যখন অ্যাট্রিবিউটটি সরিয়ে ফেলছি তখন আমি দেখতে পাচ্ছি যে তারা পাস হচ্ছে are তবে কোনও কারণে, A required anti-forgery token was not supplied or was invalid.আমি যখন বৈশিষ্ট্যটি পিছনে রাখি তখন বার্তাটি পপ আপ হয়।

কোন ধারনা?

সম্পাদনা

অ্যান্টিফোর্জিটেকেন একটি ফর্মের অভ্যন্তরে তৈরি করা হচ্ছে, তবে আমি এটি জমা দেওয়ার জন্য কোনও জমা পদক্ষেপ ব্যবহার করছি না। পরিবর্তে, আমি শুধু jquery ব্যবহার করে টোকেনের মান পাচ্ছি এবং তারপরে এজাক্স পোস্ট করার চেষ্টা করছি।

টোকেন ধারণ করে এমন ফর্মটি এখানে এবং শীর্ষস্থানীয় মাস্টার পৃষ্ঠায় অবস্থিত:

<form id="__AjaxAntiForgeryForm" action="#" method="post">
    @Html.AntiForgeryToken()
</form>

উত্তর:


288

আপনি ভুলবশত নির্দিষ্ট করে দেওয়া contentTypeথেকেapplication/json

এটি কীভাবে কাজ করবে তার একটি উদাহরণ এখানে।

নিয়ন্ত্রক:

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

    [HttpPost]
    [ValidateAntiForgeryToken]
    public ActionResult Index(string someValue)
    {
        return Json(new { someValue = someValue });
    }
}

দেখুন:

@using (Html.BeginForm(null, null, FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
    @Html.AntiForgeryToken()
}

<div id="myDiv" data-url="@Url.Action("Index", "Home")">
    Click me to send an AJAX request to a controller action
    decorated with the [ValidateAntiForgeryToken] attribute
</div>

<script type="text/javascript">
    $('#myDiv').submit(function () {
        var form = $('#__AjaxAntiForgeryForm');
        var token = $('input[name="__RequestVerificationToken"]', form).val();
        $.ajax({
            url: $(this).data('url'),
            type: 'POST',
            data: { 
                __RequestVerificationToken: token, 
                someValue: 'some value' 
            },
            success: function (result) {
                alert(result.someValue);
            }
        });
        return false;
    });
</script>

হাই, দ্রুত উত্তর দেওয়ার জন্য ধন্যবাদ। দুঃখিত আমি প্রশ্নটিতে এটি উল্লেখ করিনি; আমি এই মুহুর্তে সাবমিট অ্যাকশনটি ব্যবহার করছি না। (টোকেনটি কোনও ফর্মটিতে রয়েছে, তবে আমি এটি জমা দেওয়ার জন্য সাবমিট বাটন ব্যবহার করছি না)। বিষয়বস্তুর ধরণটি কি অন্য কিছুতে পরিবর্তন করা সম্ভব?
ওজে রাকিয়েও

13
আপনি জমা দেওয়ার ক্রিয়াটি ব্যবহার করছেন না এই বিষয়টি আমার উত্তরকে খুব বেশি পরিবর্তন করে না। আপনাকে যা করতে হবে তা হ'ল কিছু অন্যান্য ইভেন্টের সদস্যতা নিতে হবে (একটি বোতাম ক্লিক, একটি অ্যাঙ্কর ক্লিক বা যা কিছু এবং কেবল লুকানো মাঠের মান পড়ুন)। যতক্ষণ না এজেএক্স অনুরোধ প্রেরণ সম্পর্কিত, আপনি আমার উত্তরে প্রদত্ত উদাহরণটি ব্যবহার করতে পারেন। আপনার ব্যবহার contentTypeকরা উচিত নয় application/jsonকারণ সার্ভারটি __RequestVerificationTokenপ্যারামিটারটি POST অনুরোধ পেওলোডের অংশ হিসাবে ব্যবহার করে বলে প্রত্যাশা করছে application/x-www-form-urlencoded
দারিন দিমিত্রভ

এই কোডটি কীভাবে $(this).data('url'),বুঝতে পারে যে আমার নিয়ামক এবং ক্রিয়াটির url কী হবে be দয়া করে ব্যাখ্যা করুন. ধন্যবাদ
Mou

2
মূল প্রশ্নটি কন্টেন্টটাইপ সম্পর্কে ছিল: 'অ্যাপ্লিকেশন / জেসন'। ফর্ম পোস্টে __RecquestVerificationsToken সহ নিয়মিত এজাক্স পোস্টের জন্য স্পষ্টতই কাজ করবে কারণ এটি নিয়মিত ফর্ম পোস্টের মতো। আপনি যখন json পোস্ট করতে চান তবে (তাই সামগ্রীর ধরণ) এটি কার্যকর বলে মনে হয় না। সুতরাং এটি ভুল হিসাবে উত্তর হিসাবে উপরোক্ত গ্রহণ একটি ক্ষেত্রে।
জন

আমার কি "মডেলস্টেট.আইএসভালিড" ব্যবহার করা দরকার? আমি কীভাবে বলতে পারি যে এটি কাজ করছে?
মোরান মনোভিচ

61

আরেকটি (কম জাভাস্ক্রিপ্ট) পদ্ধতির, যা আমি করেছিলাম, এরকম কিছু ঘটে:

প্রথম, একজন এইচটিএমএল সহায়ক

public static MvcHtmlString AntiForgeryTokenForAjaxPost(this HtmlHelper helper)
{
    var antiForgeryInputTag = helper.AntiForgeryToken().ToString();
    // Above gets the following: <input name="__RequestVerificationToken" type="hidden" value="PnQE7R0MIBBAzC7SqtVvwrJpGbRvPgzWHo5dSyoSaZoabRjf9pCyzjujYBU_qKDJmwIOiPRDwBV1TNVdXFVgzAvN9_l2yt9-nf4Owif0qIDz7WRAmydVPIm6_pmJAI--wvvFQO7g0VvoFArFtAR2v6Ch1wmXCZ89v0-lNOGZLZc1" />
    var removedStart = antiForgeryInputTag.Replace(@"<input name=""__RequestVerificationToken"" type=""hidden"" value=""", "");
    var tokenValue = removedStart.Replace(@""" />", "");
    if (antiForgeryInputTag == removedStart || removedStart == tokenValue)
        throw new InvalidOperationException("Oops! The Html.AntiForgeryToken() method seems to return something I did not expect.");
    return new MvcHtmlString(string.Format(@"{0}:""{1}""", "__RequestVerificationToken", tokenValue));
}

এটি একটি স্ট্রিং ফিরে আসবে

__RequestVerificationToken:"P5g2D8vRyE3aBn7qQKfVVVAsQc853s-naENvpUAPZLipuw0pa_ffBf9cINzFgIRPwsf7Ykjt46ttJy5ox5r3mzpqvmgNYdnKc1125jphQV0NnM5nGFtcXXqoY3RpusTH_WcHPzH4S4l1PmB8Uu7ubZBftqFdxCLC5n-xT0fHcAY1"

সুতরাং আমরা এটি এর মতো ব্যবহার করতে পারি

$(function () {
    $("#submit-list").click(function () {
        $.ajax({
            url: '@Url.Action("SortDataSourceLibraries")',
            data: { items: $(".sortable").sortable('toArray'), @Html.AntiForgeryTokenForAjaxPost() },
            type: 'post',
            traditional: true
        });
    });
});

এবং এটা কাজ মনে হয়!


5
+1, দুর্দান্ত @Html.AntiForgeryTokenForAjaxPostএক হাতে টোকেন নাম এবং অন্য হাতে এর মান পেতে আমি কেবল দুটি বিভক্ত করেছি । অন্যথায় সিনট্যাক্স হাইলাইটটি সমস্ত গোলমেলে। এটি এর আগে শেষ হয় (প্রত্যাবর্তিত ফলাফল থেকে একক-উক্তিগুলিও সরানো হয়েছে, যাতে এটি কোনও এমভিসি সাহায্যকারীর মতো আচরণ করে, উদাহরণস্বরূপ @ ইউআরএল):'@Html.AntiForgeryTokenName' : '@Html.AntiForgeryTokenValue'
এসকোলইন

4
সুন্দর এটির সাথে আপনার কাছে অজ্যাক্স কল এন সিএসটিএম ফাইল আছে .... আপনার মতে জাজরের সাথে ম্যাক্স করা উচিত নয়।
বানি 1985

আমি এই প্রশ্নটিকে অগ্রাহ্য করেছি কারণ আমি বিশ্বাস করি যে অ্যান্টিফোরজি স্ট্যাটিক ক্লাসটি ব্যবহার করা একটি সহজ পদ্ধতির। এইচটিএমএল পাওয়া এবং সরাসরি টোকেন মান পাওয়ার পরিবর্তে এটি প্রতিস্থাপন করা খারাপ অভ্যাস। এএসপি.এনইটি সম্পূর্ণরূপে উন্মুক্ত উত্স: github.com/ASP-NET-MVC/aspnetwebstack/blob/… (তবে এখন কেবলমাত্র টোকেন পায় এমন একটি কাস্টম এক্সটেনশন পদ্ধতি সহ অন্য উত্তরটি লেখার পক্ষে মূল্যবান হতে পারে)
usr-local- ΕΨΗΕΛΩΝ

4
মাত্র টোকেন মান পাওয়ার একটি ক্লিনার উপায় হ'ল এক্সলেমেন্ট ব্যবহার করা। XElement.Parse(antiForgeryInputTag).Attribute("value").Value
darrunategui

3
@ ট্রান্সফর্মারvar antiForgeryInputTag = helper.AntiForgeryToken().ToString(); return XElement.Parse(antiForgeryInputTag).Attribute("value").Value
ডায়ারুনটেইগুই 10'18

45

এটা এত সহজ! আপনি যখন @Html.AntiForgeryToken()এইচটিএমএল কোডটি ব্যবহার করেন তার অর্থ এই যে সার্ভারটি এই পৃষ্ঠাটিতে স্বাক্ষর করেছে এবং এই নির্দিষ্ট পৃষ্ঠা থেকে সার্ভারে প্রেরিত প্রতিটি অনুরোধে একটি সাইন রয়েছে যা হ্যাকারদের দ্বারা একটি জাল অনুরোধ প্রেরণ করতে বাধা দেওয়া হয়েছে। সুতরাং এই পৃষ্ঠাটি সার্ভার দ্বারা প্রমাণীকরণের জন্য আপনার দুটি পদক্ষেপের মধ্য দিয়ে যেতে হবে:

1. নামের একটি পরামিতি প্রেরণ করুন __RequestVerificationTokenএবং নীচে এর মান ব্যবহারের কোডগুলি পান:

<script type="text/javascript">
    function gettoken() {
        var token = '@Html.AntiForgeryToken()';
        token = $(token).val();
        return token;
   }
</script>

উদাহরণস্বরূপ একটি এজ্যাক কল নিন

$.ajax({
    type: "POST",
    url: "/Account/Login",
    data: {
        __RequestVerificationToken: gettoken(),
        uname: uname,
        pass: pass
    },
    dataType: 'json',
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    success: successFu,
});

এবং পদক্ষেপ 2 কেবলমাত্র আপনার ক্রিয়া পদ্ধতিটি দ্বারা সজ্জিত করুন [ValidateAntiForgeryToken]


ধন্যবাদ, জসন পোস্টের জন্য দুর্দান্ত কাজ করে ... আমি সামগ্রীটি অনুপস্থিত ছিল টাইপ :(
স্নজিভ গুপ্ত

9

Asp.Net Core এ আপনি ডকুমেন্ট হিসাবে সরাসরি টোকেনটির জন্য অনুরোধ করতে পারেন :

@inject Microsoft.AspNetCore.Antiforgery.IAntiforgery Xsrf    
@functions{
    public string GetAntiXsrfRequestToken()
    {
        return Xsrf.GetAndStoreTokens(Context).RequestToken;
    }
}

এবং এটি জাভাস্ক্রিপ্টে ব্যবহার করুন:

function DoSomething(id) {
    $.post("/something/todo/"+id,
               { "__RequestVerificationToken": '@GetAntiXsrfRequestToken()' });
}

ডকুমেন্ট হিসাবে আপনি প্রস্তাবিত গ্লোবাল ফিল্টার যুক্ত করতে পারেন :

services.AddMvc(options =>
{
    options.Filters.Add(new AutoValidateAntiforgeryTokenAttribute());
})

হালনাগাদ

উপরের সমাধানটি স্ক্রিপ্টগুলিতে কাজ করে যা .cshtml এর অংশ। যদি এটি না হয় তবে আপনি এটি সরাসরি ব্যবহার করতে পারবেন না। আমার সমাধানটি হ'ল প্রথমে মানটি সংরক্ষণ করার জন্য একটি লুকানো ক্ষেত্র ব্যবহার করা।

আমার কাজের মত, এখনও ব্যবহার GetAntiXsrfRequestToken:

যখন কোন ফর্ম নেই:

<input type="hidden" id="RequestVerificationToken" value="@GetAntiXsrfRequestToken()">

nameঅ্যাট্রিবিউট বাদ দেওয়া যেতে পারে যেহেতু আমি ব্যবহার idঅ্যাট্রিবিউট।

প্রতিটি ফর্ম এই টোকেন অন্তর্ভুক্ত। সুতরাং কোনও লুকানো ক্ষেত্রে একই টোকেনের আর একটি অনুলিপি যুক্ত করার পরিবর্তে, আপনি কোনও বিদ্যমান ক্ষেত্রটি দ্বারা অনুসন্ধান করতে পারেন name। দয়া করে নোট করুন: একটি নথির ভিতরে একাধিক ফর্ম থাকতে পারে, তাই nameক্ষেত্রে এটি অনন্য নয়। অনন্য হওয়া উচিত এমন একটি idবৈশিষ্ট্যের মতো নয় ।

স্ক্রিপ্টে, আইডি দ্বারা সন্ধান করুন:

function DoSomething(id) {
    $.post("/something/todo/"+id,
       { "__RequestVerificationToken": $('#RequestVerificationToken').val() });
}

টোকেনটি উল্লেখ না করে একটি বিকল্প হ'ল স্ক্রিপ্ট সহ ফর্মটি জমা দেওয়া।

নমুনা ফর্ম:

<form id="my_form" action="/something/todo/create" method="post">
</form>

টোকেনটি লুকানো ক্ষেত্র হিসাবে স্বয়ংক্রিয়ভাবে ফর্মটিতে যুক্ত হয়:

<form id="my_form" action="/something/todo/create" method="post">
<input name="__RequestVerificationToken" type="hidden" value="Cf..." /></form>

এবং স্ক্রিপ্টে জমা দিন:

function DoSomething() {
    $('#my_form').submit();
}

অথবা একটি পোস্ট পদ্ধতি ব্যবহার করে:

function DoSomething() {
    var form = $('#my_form');

    $.post("/something/todo/create", form.serialize());
}

আমি মনে করি এই সমাধানটি কেবল তখনই কাজ করে যদি আপনার জাভাস্ক্রিপ্টটি আপনার সিএসটিএমএল ফাইলে থাকে।
carlin.scott

6

Asp.Net MVC এ যখন আপনি @Html.AntiForgeryToken()রেজার ব্যবহার করেন তখন __RequestVerificationTokenটোকেন সঞ্চয় করার জন্য নামের সাথে একটি লুকানো ইনপুট ক্ষেত্র তৈরি করে । আপনি যদি একটি এজেএক্স বাস্তবায়ন লিখতে চান তবে আপনাকে নিজের টোকেনটি এনে সার্ভারে একটি পরামিতি হিসাবে দিতে হবে যাতে এটি বৈধতা পেতে পারে।

পদক্ষেপ 1: টোকেন পান

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

পদক্ষেপ 2: AJAX কলটিতে টোকেনটি পাস করুন

function registerStudent() {

var student = {     
    "FirstName": $('#fName').val(),
    "LastName": $('#lName').val(),
    "Email": $('#email').val(),
    "Phone": $('#phone').val(),
};

$.ajax({
    url: '/Student/RegisterStudent',
    type: 'POST',
    data: { 
     __RequestVerificationToken:token,
     student: student,
        },
    dataType: 'JSON',
    contentType:'application/x-www-form-urlencoded; charset=utf-8',
    success: function (response) {
        if (response.result == "Success") {
            alert('Student Registered Succesfully!')

        }
    },
    error: function (x,h,r) {
        alert('Something went wrong')
      }
})
};

দ্রষ্টব্য : সামগ্রীর ধরণটি হওয়া উচিত'application/x-www-form-urlencoded; charset=utf-8'

আমি প্রকল্পটি গিথুবে আপলোড করেছি; আপনি এটি ডাউনলোড করে দেখতে পারেন।

https://github.com/lambda2016/AjaxValidateAntiForgeryToken


আমি এখানে শিক্ষার্থী ফর্ম সিরিয়ালাইজটি কীভাবে ব্যবহার করতে পারি: $ ('# ফ্রেম-শিক্ষার্থী')। সিরিয়ালাইজ (),
লিটলড্রাগন ২

6

        ফাংশন ডিলিট্পারসোনেল (আইডি)

                var ডেটা = নতুন ফর্মডাটা ();
                ডেটা.এপেন্ড ("__ রিকোয়েস্টফেরিফিকেশন টোকেন", "@ এইচটিএমএলহেল্পার.গেটআন্টিফোরজিটোকেন ()");

                .ajax $ ({
                    প্রকার: 'পোস্ট',
                    url: '/ পার্সোনেল / মুছুন /' + আইডি,
                    ডেটা: ডেটা,
                    ক্যাশে: মিথ্যা,
                    প্রক্রিয়াডাটা: মিথ্যা,
                    কন্টেন্ট টাইপ: মিথ্যা,
                    সাফল্য: ফাংশন (ফলাফল)

                    }
                });

        }
    

        পাবলিক স্ট্যাটিক ক্লাস এইচটিএমএল হেল্পার
        {
            পাবলিক স্ট্যাটিক স্ট্রিং গেটআন্টিফোরজিটোকেন ()
            {
                System.Text.RegularExpressions.Match value = System.Text.RegularExpressions.Regex.Match (System.Web.Helpers.AntiForgery.GetHtml ()। ToString (), "(?: Value = \") (। *) (?)? : \ ")");
                যদি (মান। সাফল্য)
                {
                    প্রত্যাবর্তন মান .গোষ্ঠী [1] .মূল্য;
                }
                ফিরে "";
            }
        }

3

আমি জানি এটি একটি পুরানো প্রশ্ন। তবে আমি যাইহোক আমার উত্তর যুক্ত করব, আমার মতো কাউকে সাহায্য করতে পারে।

আপনি যদি কন্ট্রোলারের LoggOffপদ্ধতি কল করার মতো নিয়ন্ত্রকের পোস্ট ক্রিয়াকলাপ থেকে ফলাফলটি প্রক্রিয়া করতে না চান তবে আপনি Accounts@ ডারিনডিমিট্রভের উত্তরের নিম্নলিখিত সংস্করণ হিসাবে করতে পারেন:

@using (Html.BeginForm("LoggOff", "Accounts", FormMethod.Post, new { id = "__AjaxAntiForgeryForm" }))
{
    @Html.AntiForgeryToken()
}

<!-- this could be a button -->
<a href="#" id="ajaxSubmit">Submit</a>

<script type="text/javascript">
    $('#ajaxSubmit').click(function () {

        $('#__AjaxAntiForgeryForm').submit();

        return false;
    });
</script>

3

অ্যাকাউন্ট নিয়ামক:

    // POST: /Account/SendVerificationCodeSMS
    [HttpPost]
    [AllowAnonymous]
    [ValidateAntiForgeryToken]
    public JsonResult SendVerificationCodeSMS(string PhoneNumber)
    {
        return Json(PhoneNumber);
    }

দেখুন:

$.ajax(
{
    url: "/Account/SendVerificationCodeSMS",
    method: "POST",
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    dataType: "json",
    data: {
        PhoneNumber: $('[name="PhoneNumber"]').val(),
        __RequestVerificationToken: $('[name="__RequestVerificationToken"]').val()
    },
    success: function (data, textStatus, jqXHR) {
        if (textStatus == "success") {
            alert(data);
            // Do something on page
        }
        else {
            // Do something on page
        }
    },
    error: function (jqXHR, textStatus, errorThrown) {
        console.log(textStatus);
        console.log(jqXHR.status);
        console.log(jqXHR.statusText);
        console.log(jqXHR.responseText);
    }
});

সেট contentTypeকরা 'application/x-www-form-urlencoded; charset=utf-8'বা contentTypeঅবজেক্ট থেকে বাদ দেওয়া গুরুত্বপূর্ণ ...


আসলেই ব্যবহারিক নয়, এর অর্থ আপনাকে প্রতিটি ফর্মটি কোড আপ করতে হবে এবং ফর্মগুলির অনেকগুলি উপাদান থাকলে এটি ব্যথা হতে পারে :(
djack109

0

আমি প্রচুর ওয়ার্ক্রাউন্ডে চেষ্টা করেছি এবং সেগুলি আমার পক্ষে কাজ করে নি। ব্যতিক্রমটি ছিল "প্রয়োজনীয় অ্যান্টি-জালিয়াতি ফর্ম ক্ষেত্র" __RecquestVerificationsToken "।

আমাকে যা সাহায্য করেছিল তা হ'ল ফর্মটি .jax। পোস্টে স্যুইচ করা:

$.post(
    url,
    $(formId).serialize(),
    function (data) {
        $(formId).html(data);
    });

0

নিচে ফাংশনটি নির্দ্বিধায় ব্যবহার করুন:

function AjaxPostWithAntiForgeryToken(destinationUrl, successCallback) {
var token = $('input[name="__RequestVerificationToken"]').val();
var headers = {};
headers["__RequestVerificationToken"] = token;
$.ajax({
    type: "POST",
    url: destinationUrl,
    data: { __RequestVerificationToken: token }, // Your other data will go here
    dataType: "json",
    success: function (response) {
        successCallback(response);
    },
    error: function (xhr, status, error) {
       // handle failure
    }
});

}


0

টোকেনটি যদি অন্য কোনও নিয়ামক সরবরাহ করে তবে তা কাজ করবে না। যেমন যদি দৃশ্য দ্বারা ফিরে ছিল কাজ করবে না Accountsনিয়ামক, কিন্তু আপনি POSTকরতে Clientsনিয়ামক।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.