jQuery আজাক্স কল এবং এইচটিএমএল.আন্টিফোরজিটোকেন ()


207

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

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

1) [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 সহ আজাক্স পোস্ট করছি। এটি ঘটে উদাহরণস্বরূপ যেখানে আমি ব্যবহারকারীকে একটি নির্দিষ্ট ক্রিয়া করতে কোনও চিত্রটিতে ক্লিক করতে দিচ্ছি।

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

$("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) {
            // ....
        }
    });
});

ডেভিড হেডেন লিংক এখন 404s, দেখে মনে হচ্ছে তিনি নতুন CMS এ তার ব্লগে হিজরত, কিন্তু সব বয়সী বিষয়বস্তু মাইগ্রেট করা হয়নি।

উত্তর:


252

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

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({
    type: "post",
    dataType: "html",
    url: $(this).attr("rel"),
    data: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
    success: function (response) {
        // ....
    }
});

6
ভাল লাগল, আমি টোকেন আনার এনক্যাপসুলেশন পছন্দ করি।
jball

2
@ লরেঞ্জো, আপনার কাস্টম ডেটা কলটির অভ্যন্তরে AddAntiForgeryTokendata: AddAntiForgeryToken({ id: parseInt($(this).attr("title")) }),
রাখুন

3
জালিয়াতির বিরোধী টোকেনটি সর্বদা বাড়ানোর জন্য কোনও ধারণা ব্যবহার করা ajaxSendবা ওভাররাইড ajaxকরা কত খারাপ হবে data? urlআপনার সার্ভারের জন্য এটি নির্ধারিত রয়েছে তা নিশ্চিত করতে কিছু চেক যোগ করতে পারে ।
ta.speot.is

1
আপনি যদি আউটপুট ক্যাশে ব্যবহার করেন তবে সাবধান হন।
বার্বারোস আল্প

1
@ সোহাইববেস বৈধকরণ টোকেনটি সমস্ত পৃষ্ঠাগুলির ব্যবহারকারীর জন্য সমান হওয়া উচিত (এটি সেট করে থাকা কুকির সাথে একত্রে কাজ করে এবং একই থাকে)। সুতরাং প্রতি পৃষ্ঠায় একাধিক অনুরোধ রয়েছে কিনা তাতে কিছু যায় আসে না, বেস পৃষ্ঠাটি যাইহোক পুনরায় লোড করা হলে এটি একই হবে।
জেরেমিওয়েয়ার

29

আমি 360Airwalk দ্বারা সরবরাহিত সমাধানটি পছন্দ করি তবে এটি কিছুটা উন্নত হতে পারে।

প্রথম সমস্যাটি হ'ল যদি আপনি $.post()খালি ডেটা তৈরি করেন তবে jQuery কোনও Content-Typeশিরোনাম যুক্ত করে না এবং এই ক্ষেত্রে ASP.NET MVC টোকেনটি গ্রহণ ও পরীক্ষা করতে ব্যর্থ হয়। সুতরাং আপনাকে নিশ্চিত করতে হবে যে শিরোলেখ সর্বদা থাকে।

আরেকটি উন্নতি হ'ল সামগ্রী সম্পর্কিত সমস্ত এইচটিটিপি ক্রিয়াগুলির সমর্থন : পোষ্ট, পুট, মোছা ইত্যাদি you যদিও আপনি আপনার অ্যাপ্লিকেশনটিতে কেবলমাত্র পোষ্ট ব্যবহার করতে পারেন তবে জেনেরিক সমাধান হওয়া ভাল এবং আপনার যে কোনও ক্রিয়া দিয়ে প্রাপ্ত সমস্ত ডেটা একটি অ্যান্টি-জালিয়াতি রয়েছে তা যাচাই করা ভাল better টোকেন.

$(document).ready(function () {
    var securityToken = $('[name=__RequestVerificationToken]').val();
    $(document).ajaxSend(function (event, request, opt) {
        if (opt.hasContent && securityToken) {   // handle all verbs with content
            var tokenParam = "__RequestVerificationToken=" + encodeURIComponent(securityToken);
            opt.data = opt.data ? [opt.data, tokenParam].join("&") : tokenParam;
            // ensure Content-Type header is present!
            if (opt.contentType !== false || event.contentType) {
                request.setRequestHeader( "Content-Type", opt.contentType);
            }
        }
    });
});

1
+1 আপনি ঠিক বলেছেন, আমি খালি পোস্ট কল ইস্যু নিয়ে ভাবি নি। ইনপুট জন্য ধন্যবাদ. আপনি ঠিক বলেছেন যে আমরা আমাদের প্রকল্পে এখনও মুছে ফেলতে / রাখা ব্যবহার করি না।
360Airwalk

2
সমস্ত jQuery.Ajax কলগুলিতে আমাকে ফাংশনটি যুক্ত করা থেকে বাঁচানোর জন্য +1
ড্রাগাগস ডুরলুট

2
+1 ঠিক .ajaxSend()উত্তরসূরির জন্য একটি নোট হিসাবে, jQuery ডকুমেন্টেশন "jQuery 1.8 হিসাবে, .ajaxSend () পদ্ধতিটি কেবলমাত্র নথির সাথে সংযুক্ত থাকা উচিত states" api.jquery.com/ajaxsend
আরজে কুথবার্টসন

1
@ ব্রঙ্কস optionsচূড়ান্ত ifবিবৃতিতে তালিকাভুক্ত কোনটি এসেছে ? ধন্যবাদ।
hvaughan3

আপনার কোনও পৃষ্ঠায় একাধিক ফর্ম থাকলে এটি ব্যবহার থেকে সাবধান থাকুন। আপনাকে ডকুমেন্টের পরিবর্তে আরও সুনির্দিষ্ট নির্বাচক কল দিয়ে পাঠাতে আগে সেট করতে হবে।
ড্যান

22

আমি জানি যে আরও অনেক উত্তর রয়েছে তবে এই নিবন্ধটি দুর্দান্ত এবং সংক্ষিপ্ত এবং আপনাকে এইচটিটিপিপोस्স্টগুলি কেবলমাত্র তাদের মধ্যে কয়েকটি নয় যাচাই করতে বাধ্য করে:

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 () {
        ...
    }
});

4
আপনি ব্রঙ্কসের প্রতিক্রিয়াটির সাথে মিলিত নিবন্ধের বৈশিষ্ট্য হ'ল এই সমস্যার চূড়ান্ত ডিআরওয়াই সমাধান।
TugboatCaptain

2
দুর্দান্ত খুঁজে। কোড স্নিপেটগুলি অন্তর্ভুক্ত করার জন্য আমি আপনার উত্তর সম্পাদনা করেছি যাতে উত্তরটি নিজেরাই দাঁড়িয়ে থাকে তবে আমি আশা করি লোকেরা বাকী নিবন্ধটিও পড়বে। এটি একটি খুব পরিষ্কার সমাধান বলে মনে হচ্ছে।
টিম মেডোরা

ধন্যবাদ টিম, এটি একটি দুর্দান্ত ধারণা, যখন কোনও লিঙ্ক মারা যায় এবং উত্তরটি মূল্যহীন হয়ে যায় তখন হতাশ। আমি আমার সমস্ত নতুন উত্তরের উপর এটি করা শুরু করেছি।
স্নিগ্ধতা

এটি কি এমভিসি, ওয়েবএপিআই বা নেট নেট? আমি ওয়েবএপিআই 5
মিস্টার

20

আমি এখানে উন্নত নেক্রোম্যান্সারের মতো অনুভব করি তবে এমভিসি 5 এ এটি 4 বছর পরে এখনও একটি সমস্যা।

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

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

_Layout.cshtml

_Layout.cshtml এ আমার এই জাভাস্ক্রিপ্ট ব্লক আছে। এটি ডিওমে টোকেনটি লিখে না, বরং এমভিসি হেল্পার তৈরি করে এমন লুকানো ইনপুট আক্ষরিক থেকে এটিকে বের করতে jQuery ব্যবহার করে। শিরোনামের নাম হ'ল ম্যাজিক স্ট্রিংটি অ্যাট্রিবিউট শ্রেণিতে ধ্রুবক হিসাবে সংজ্ঞায়িত করা হয়।

<script type="text/javascript">
    $(document).ready(function () {
        var isAbsoluteURI = new RegExp('^(?:[a-z]+:)?//', 'i');
        //http://stackoverflow.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>

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

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

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

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

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

অ-মানক টোকেনটি প্রক্রিয়া করার জন্য একটি কাস্টম বৈশিষ্ট্য প্রয়োজন। এটি @ সার্থকতার সমাধানের উপর ভিত্তি করে, তবে নিরর্থক এজাক্সকে সঠিকভাবে পরিচালনা করে। এই কোডটি আপনার সাধারণ লাইব্রেরিতে সরিয়ে ফেলা যায়

[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);
}

নিখুঁত সমাধান, অনেক বেশি কেন্দ্রীভূত। ধন্যবাদ
ডেভিড ফ্রেইর

আপনি কেন কেবলমাত্র আপেক্ষিক ইউআরএলগুলির জন্য শিরোনাম যুক্ত করতে চান তা আরও বিশদে ব্যাখ্যা করতে পারেন? এটা আমার মাথার উপর দিয়ে গেল দুর্দান্ত সমাধান!
ম্যাটএম

আপেক্ষিক নিশ্চিত করে যে শিরোনামটি কেবলমাত্র আপনার নিজের সার্ভারে ফিরে যাওয়ার অনুরোধগুলিতে সেট করা আছে, এজ্যাক্স অ্যাজাক্স সেটআপটি jquery সহ করা সমস্ত অনুরোধকে কভার করে, আমরা টোকনটি jsonp বা CORS রিকোয়েটে প্রেরণ করা চাই না। এটি পরম ইউআরএলগুলির জন্যও সত্য, তবে আপেক্ষিক একই ডোমেন হিসাবে গ্যারান্টিযুক্ত।
উইল ডি

1
@ উইলডি আমি আপনার সমাধানটি পছন্দ করেছি তবে এটি কিছুটা সংশোধন করতে বাধ্য হয়েছিল। যেহেতু আপনি $.ajaxSetupএকটি সাধারণ beforesendইভেন্টহ্যান্ডলার সংজ্ঞায়িত করতে পছন্দ করেন এটি এমন হতে পারে যে আপনি এটি ওভাররাইট করে ফেলেছেন। আমি আর একটি সমাধান পেয়েছি যেখানে আপনি দ্বিতীয় হ্যান্ডলার যুক্ত করতে পারেন যা আপনাকে ডাকা হবে। সুন্দরভাবে কাজ করে এবং আপনার বাস্তবায়ন ভঙ্গ করে না।
ভাইপার

গ্রাহকের এএসপিএনটি 5 সংস্করণটি কি অ্যান্টিফোররি বৈশিষ্ট্যটি যাচাই করে? এই সংস্করণটি সর্বশেষতম সংস্করণে সংকলন করে না!
রব ম্যাককেবে

19

এইচটিএমএল.অ্যান্টিফজারি টোকেন ব্যবহার করবেন না । পরিবর্তে, এএসপি.নেট এমভিসি অ্যাপ্লিকেশনটিতে ক্রস-সাইট রিকোয়েস্ট ফোরজি (সিএসআরএফ) আক্রমণ প্রতিরোধে বর্ণিত হিসাবে ওয়েব এপিআই থেকে অ্যান্টিফর্গ্রি.গেটটোকেনস এবং অ্যান্টিফগেরি.ভালিডেট ব্যবহার করুন ।


নিয়ন্ত্রক অ্যাকশন পদ্ধতির জন্য যে মডেল কোনও সার্ভার মডেল টাইপ পোস্ট এজেএক্স জেএসওনকে আবদ্ধ করে, সঠিক অ্যাপ্লিকেশন বাইন্ডার ব্যবহারের জন্য "অ্যাপ্লিকেশন / জেসন" হিসাবে কনটেন্ট টাইপ থাকা আবশ্যক। দুর্ভাগ্যক্রমে, এটি [ValidateAntiForgeryToken] অ্যাট্রিবিউট দ্বারা প্রয়োজনীয় ফর্ম ডেটা ব্যবহার করা বন্ধ করে দেয়, সুতরাং আপনার পদ্ধতিটি এটির কাজ করার জন্য আমি খুঁজে পেলাম way আমার একটাই প্রশ্ন, এটি কি এখনও একটি ওয়েব ফার্মে বা একাধিক অ্যাজুরে ওয়েব রোল উদাহরণগুলিতে কাজ করে? আপনি কি অ্যাডওয়ার্ড, বা অন্য কেউ জানেন যে এটি সমস্যা কিনা?
রিচার্ড বি

@ অ্যাডওয়ার্ড বেরি আপনি দয়া করে কেন এটি ব্যবহার করবেন না তা বিস্তারিত বলতে পারেন?
ওডিস

4
@ ওডিস: এইচটিএমএল.অ্যান্টিফজারি টোকেনের সাথে অন্তর্নিহিত কোনও ভুল নেই, তবে এর ডাউনসাইড রয়েছে: একটি ফর্মের প্রয়োজন, jQuery প্রয়োজন, এবং অনির্ধারিত এইচটিএমএল.আন্টিফোরজিটোকেন বাস্তবায়ন বিশদটি ধরে নিয়েছে। তবুও, এটি অনেক প্রসঙ্গে ভাল। আমার বক্তব্য "এইচটিএমএল ব্যবহার করবেন না। অ্যান্টিফোর্জিটোকেন" সম্ভবত খুব শক্তিশালী। আমার অর্থ হ'ল এটি ওয়েব এপিআইয়ের সাথে ব্যবহারের উদ্দেশ্যে নয়, যেখানে আরও নমনীয় অ্যান্টিফর্গ্রি.গেটটোকেনস।
এডওয়ার্ড ব্রে

ধন্যবাদ! এটি কোনও এমভিসি 5 কন্ট্রোলারের জন্য কাজ করার জন্য আমাকে কিছুটা পরিবর্তন করতে হয়েছিল, তবে এটি সমাধান ছিল
জাও

3
এটি অবশ্যই একটি ফর্ম প্রয়োজন হয় না। আপনাকে কেবল এটির জন্য ডোমকে বিশ্লেষণ করতে হবে। জ্যাকোয়ারি ব্যবহার করে, আমি এটি ডেটা via __RecquestVerificationsToken: $ ("ইনপুট [নাম = __ রিকোয়েস্টফেরিফিকেশন টোকেন]" এর মাধ্যমে এটিকে আমার ডেটা অবজেক্টের সাথে যুক্ত করতে পারি) ভাল ()}
অ্যান্টনি ম্যাসন

16

আমি আমার বর্তমান প্রকল্পে এই বাস্তব সমস্যাটি বাস্তবায়ন করছিলাম। আমি এটি সমস্ত এজাক্স-পোষ্টগুলির জন্য করেছিলাম যার জন্য একটি প্রমাণীকৃত ব্যবহারকারীর প্রয়োজন।

প্রথমে আমি আমার জ্যাকোরি এজ্যাক্স কলগুলিকে হুক করার সিদ্ধান্ত নিয়েছি যাতে আমি নিজেকে প্রায়শই পুনরাবৃত্তি না করি। এই জাভাস্ক্রিপ্ট স্নিপেট নিশ্চিত করে যে সমস্ত এজাক্স (পোস্ট) কলগুলি অনুরোধে আমার অনুরোধের বৈধতা টোকেন যুক্ত করবে। দ্রষ্টব্য: __RecquestVerificationsToken নামটি। নেট ফ্রেমওয়ার্ক দ্বারা ব্যবহৃত হয় যাতে আমি নীচের চিত্রের মতো মানক অ্যান্টি-সিএসআরএফ বৈশিষ্ট্যগুলি ব্যবহার করতে পারি।

$(document).ready(function () {
    var securityToken = $('[name=__RequestVerificationToken]').val();
    $('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);
            }
        }
    });
});

আপনার দর্শনে যেখানে উপরের জাভাস্ক্রিপ্টের জন্য টোকেনটি উপলব্ধ থাকতে হবে কেবল সাধারণ এইচটিএমএল-সহায়ক ব্যবহার করুন। আপনি চাইলে এই কোডটি মূলত যুক্ত করতে পারেন। আমি এটি যদি (অনুরোধ.আইএসআউটিকৃত) বিবৃতিতে রেখেছি:

@Html.AntiForgeryToken() // you can provide a string as salt when needed which needs to match the one on the controller

আপনার নিয়ামকটিতে কেবল স্ট্যান্ডার্ড এএসপি.নেট এমভিসি অ্যান্টি-সিএসআরএফ প্রক্রিয়াটি ব্যবহার করুন। আমি এটি এর মতো করেছিলাম (যদিও আমি প্রকৃতপক্ষে লবণ ব্যবহার করি)।

[HttpPost]
[Authorize]
[ValidateAntiForgeryToken]
public JsonResult SomeMethod(string param)
{
    // do something
    return Json(true);
}

ফায়ারব্যাগ বা অনুরূপ সরঞ্জামের সাহায্যে আপনি সহজেই দেখতে পাবেন যে কীভাবে আপনার পোস্টের অনুরোধগুলিতে এখন একটি __RecquestVerificationsToken প্যারামিটার যুক্ত করা আছে।


15

আমি মনে করি আপনাকে যা করতে হবে তা নিশ্চিত করা উচিত যে "__RecquestVerificationsToken" ইনপুটটি পোষ্ট অনুরোধের অন্তর্ভুক্ত রয়েছে। অন্যান্য অর্ধেক তথ্য (যেমন ব্যবহারকারীর কুকিতে টোকেন) ইতিমধ্যে একটি এজেএক্স পোস্ট অনুরোধের সাথে স্বয়ংক্রিয়ভাবে প্রেরণ করা হয়েছে।

যেমন,

$("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) {
            // ....
        }
    });
});

1
এমভিসি (রেজার) পৃষ্ঠার মধ্য থেকে jQuery AJAX পোস্ট করার পরে বেশ কয়েক ঘন্টা পরীক্ষা-নিরীক্ষা করার পরে এটি আমার পক্ষে কাজ করা সবার সহজ উত্তর ছিল। টোকেনের পরে কেবলমাত্র নিজের নিজস্ব ডেটা ক্ষেত্রগুলি (বা ভিউমোডেল আমি মনে করি) ডেটার একটি নতুন অংশ হিসাবে অন্তর্ভুক্ত করুন (তবে মূল ডেটা অবজেক্টের মধ্যে)।
রাল্ফ বেকন

যদি এজেএক্স ফাংশন একটি .html পৃষ্ঠায় ছিল এবং রেজার পৃষ্ঠায় না ছিল তবে আমি কীভাবে এটি বাস্তবায়ন করব?
বব দ্য বিল্ডার

আপনার এইচটিএমএল পৃষ্ঠায় যদি কোনও সার্ভার সরবরাহ না করে তবে তা AntiForgeryTokenসবই শেষ হয়ে যায়। যদি এটি হয় (আপনি কীভাবে এই ক্ষেত্রে একজন হচ্ছেন তা নিশ্চিত নয়, তবে ধরে নিচ্ছেন যে আপনি আছেন) তবে উপরেরটি ঠিক কাজ করবে। আপনি যদি এমন কোনও ওয়েবপৃষ্ঠা তৈরি করার চেষ্টা করছেন যা কোনও সার্ভারের কাছে অনুরোধ পোস্ট করে যা প্রত্যাশা করে টোকেন বলেছে, এবং সার্ভারটি সেই পৃষ্ঠাটি উত্পন্ন করেনি, তবে আপনি ভাগ্য থেকে দূরে রয়েছেন। এটি মূলত অ্যান্টিফোরজি টোকেনের বিষয় ...
জবল

6

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

$("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বাক্য গঠন ব্যবহার করছেন তবে আপনি পাশাপাশি <%= %>ট্যাগ ব্যবহার করতে পারেন


4

@ জাবাল এর উত্তরের বিরুদ্ধে আমার মন্তব্যে আরও যে আমাকে পথে সহায়তা করেছিল, এটিই আমার পক্ষে চূড়ান্ত উত্তর। আমি এমভিসি এবং রেজার ব্যবহার করছি এবং আমি jQuery AJAX ব্যবহার করে একটি ফর্ম জমা দিচ্ছি যাতে আমি কিছু নতুন ফলাফলের সাথে একটি আংশিক দৃশ্য আপডেট করতে পারি এবং আমি একটি সম্পূর্ণ পোস্টব্যাক (এবং পৃষ্ঠা ফ্লিকার) করতে চাইনি।

যুক্ত করুন @Html.AntiForgeryToken() যথারীতি ফর্ম ভিতরে।

আমার AJAX জমা দেওয়ার বোতাম কোড (অর্থাত্ একটি অন্লিক ইভেন্ট) হ'ল:

//User clicks the SUBMIT button
$("#btnSubmit").click(function (event) {

//prevent this button submitting the form as we will do that via AJAX
event.preventDefault();

//Validate the form first
if (!$('#searchForm').validate().form()) {
    alert("Please correct the errors");
    return false;
}

//Get the entire form's data - including the antiforgerytoken
var allFormData = $("#searchForm").serialize();

// The actual POST can now take place with a validated form
$.ajax({
    type: "POST",
    async: false,
    url: "/Home/SearchAjax",
    data: allFormData,
    dataType: "html",
    success: function (data) {
        $('#gridView').html(data);
        $('#TestGrid').jqGrid('setGridParam', { url: '@Url.Action("GetDetails", "Home", Model)', datatype: "json", page: 1 }).trigger('reloadGrid');
    }
});

আমি "সাফল্য" অ্যাকশনটিতে রেখেছি কারণ এটি দেখায় যে আংশিক দৃষ্টিভঙ্গি কীভাবে আপডেট করা হচ্ছে যাতে এমভিসিজেকিগ্রিড রয়েছে এবং কীভাবে তা সতেজ করা হচ্ছে (অত্যন্ত শক্তিশালী জেকিগ্রিড গ্রিড এবং এটি এর জন্য একটি উজ্জ্বল এমভিসি র‌্যাপার)।

আমার নিয়ামক পদ্ধতিটি দেখতে এমন দেখাচ্ছে:

    //Ajax SUBMIT method
    [ValidateAntiForgeryToken]
    public ActionResult SearchAjax(EstateOutlet_D model) 
    {
        return View("_Grid", model);
    }

মডেল হিসাবে পুরো ফর্মের ডেটা পোস্ট করার অনুরাগী না হওয়ার কথা আমাকে স্বীকার করতে হবে তবে আপনাকে যদি এটি করা দরকার হয় তবে এটি একটি উপায় যা কাজ করে। এমভিসি কেবলমাত্র 16 টি পৃথক মান (বা একটি দুর্বলভাবে টাইপযুক্ত ফর্ম সংগ্রহ) সাবটাইটের চেয়ে ডেটা বাঁধার খুব সহজ করে তোলে এটি ঠিক আছে, আমার ধারণা। আপনি যদি আরও ভাল জানেন তবে দয়া করে আমাকে জানান, আমি শক্ত এমভিসি সি # কোড উত্পাদন করতে চাই।


4

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

// 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();
        }
    }
});

আমি উপরের অন্যান্য কয়েকটি বিকল্পের চেষ্টা করেছি, এটিই আমার জন্য সমাধান করেছে solved
হোস্টমাইবাস

তবে আমাকে if (options.contentType != false && options.contentType.indexOf('application/json') === 0) {অ্যাজাক্স কলগুলি যোগ করতে হবে যা কোনও সামগ্রীর ধরণ নির্দিষ্ট করে নি
হোস্টমাইবাস

3

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)
       });

৩. আপনি যে পদ্ধতিতে পোস্ট / হ্যান্ডেল করেন তাতে 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);

1

আমি জানি যে এই প্রশ্নটি পোস্ট হওয়ার পরে বেশ কিছুদিন হয়েছে, কিন্তু আমি সত্যিই দরকারী উত্স পেয়েছি, যা অ্যান্টিফোর্জিটোকেনের ব্যবহার নিয়ে আলোচনা করে এবং এটি ব্যবহার করতে কম ঝামেলা করে। এটি এজেএক্স কলগুলিতে সহজেই অ্যান্টিফোর্জি টোকেন সহ jquery প্লাগইন সরবরাহ করে:

এএসপি.নেট এমভিসি এবং এজেএক্সের জন্য অ্যান্টি-জালিয়াতির অনুরোধ রেসিপি

আমি খুব বেশি অবদান রাখছি না, তবে সম্ভবত কেউ এটির কাজে লাগবে।


সেই পোস্টটি মাইলের মতো দীর্ঘ! আমি নিশ্চিত যে এটি দুর্দান্ত তবে tl; ডাঃ
ব্রিটিশ ডেভেলপার

1
খুব খারাপ, কারণ এটি দুর্দান্তভাবে বিষয়টিকে কভার করে। এটি কেবল আপনাকে কীভাবে বৈশিষ্ট্যটি ব্যবহার করবেন তা বলে না, তবে এটি কী সমস্যার সমাধান করে তা ব্যাখ্যা করে এবং কীভাবে এটি সঠিকভাবে ব্যবহার করতে হয় তা বোঝার জন্য আপনাকে প্রসঙ্গ দেয়। এটি যখন সুরক্ষার কথা আসে তখন আমি গভীরভাবে বোঝা জরুরি বলে মনে করি।
স্ল্যাভেক

2
যদি এটি গুরুত্বপূর্ণ হয় তবে এটি এমনভাবে লেখা উচিত যাতে লোকেরা এটি পড়তে উত্সাহিত করে;)
ব্রিটিশ ডেভেলপার

1

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

 $.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);
        }

1

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

  $("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
        });
    });

0

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

$(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);
            }
        }
    });
});

0
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 "";
    }
}

0

আমি মুছে ফেলা পদ্ধতি চালানোর জন্য একটি এজাক্স পোস্ট ব্যবহার করছি (ভিজজ টাইমলাইনের হতে পারে তবে এটি রিলেভেন্ট নয়)। এই আমি sis:

এটি আমার সূচক। Cshtml

@Scripts.Render("~/bundles/schedule")
@Styles.Render("~/bundles/visjs")
@Html.AntiForgeryToken()

<!-- div to attach schedule to -->
<div id='schedule'></div>

<!-- div to attach popups to -->
<div id='dialog-popup'></div>

আমি এখানে যুক্ত সমস্ত ছিল @Html.AntiForgeryToken() যা কিছু টোকেনটি পৃষ্ঠায় প্রদর্শিত হবে

তারপরে আমার এজাক্স পোস্টে আমি ব্যবহার করেছি:

$.ajax(
    {
        type: 'POST',
        url: '/ScheduleWorks/Delete/' + item.id,
        data: {
            '__RequestVerificationToken': 
            $("input[name='__RequestVerificationToken']").val()
              }
     }
);

যা পোস্ট ক্ষেত্রগুলিতে টোকেন মান যুক্ত করে, পৃষ্ঠাটি সরিয়ে স্ক্র্যাপ করে

এর আগে আমি মানটি শিরোনামগুলিতে রাখার চেষ্টা করেছি তবে আমি একই ত্রুটি পেয়েছি

উন্নতি পোস্ট নির্দ্বিধায়। এটি অবশ্যই একটি সহজ পদ্ধতির বলে মনে হচ্ছে যা আমি বুঝতে পারি


0

ঠিক আছে এখানে প্রচুর পোস্ট, এর মধ্যে কেউই আমাকে, গুগলের দিনগুলি এবং দিনগুলিতে সহায়তা করেনি এবং এরপরে আর কোনও কিছুই আমি স্ক্র্যাচ থেকে পুরো অ্যাপটি আঁকতে লিখতে পয়েন্ট পাইনি, এবং তারপরে আমি আমার ওয়েবকন্টে এই ছোট্ট নোটটি লক্ষ্য করেছি noticed

 <httpCookies requireSSL="false" domain="*.localLookup.net"/>

আমি জানি না কেন আমি কেন এটি যুক্ত করেছি তবে আমি এটি লক্ষ্য করেছি, এটি ডিবাগ মোডে উপেক্ষা করা হয়েছে এবং কোনও প্রোডাকশন মোডে নয় (IE কোথাও আইআইএস ইনস্টলড)

আমার জন্য সমাধানটি দুটি বিকল্পগুলির মধ্যে একটি ছিল, যেহেতু আমি কেন এটি যুক্ত করেছিলাম তা আমি মনে করি না কারণ আমি নিশ্চিত হতে পারি যে অন্যান্য জিনিসগুলি এর উপর নির্ভর করে না এবং দ্বিতীয়ত ডোমেন নামটি অবশ্যই সমস্ত নিম্নতর হওয়া উচিত এবং একটি টিএলডি আইভির মতো নয় * .localLookup.net এ

সম্ভবত এটি সাহায্য করে সম্ভবত এটি না। আমি আশা করি এটি কারও সাহায্য করবে


0

আমি যে সলিউশন পেয়েছি তা এএসপিএক্সের জন্য নয় বরং রেজারের জন্য, তবে বেশ দক্ষ সমস্যাযুক্ত।

আমি অনুরোধে অ্যান্টিফর্জি যুক্ত করে এটি সমাধান করেছি। এইচটিএমএল সাহায্যকারী কল সহ একটি HTML আইডি তৈরি করে না

@Html.AntiForgeryToken()

পোস্টেরোয়েস্টে টোকেন যুক্ত করার জন্য আমি জ্যাকুইয়ের সাথে গোপন ক্ষেত্রে অ্যান্টিফোররি আইডি যুক্ত করেছি:

$("input[name*='__RequestVerificationToken']").attr('id', '__AjaxAntiForgeryForm');

এটি নিয়ন্ত্রককে [ValidateAntiForgeryToken] বৈশিষ্ট্যের সাথে অনুরোধটি গ্রহণ করতে বাধ্য করেছিল


-3

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

হিসাবে সমাধান করা:

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

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

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

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