ฟิลด์แบบฟอร์มป้องกันการปลอมที่จำเป็น“ __RequestVerificationToken” ไม่มีข้อผิดพลาดในการลงทะเบียนผู้ใช้


141

ฉันใช้Membership.createฟังก์ชั่นผู้ใช้แล้วเกิดข้อผิดพลาดต่อไปนี้

ฟิลด์แบบฟอร์มป้องกันการปลอมแปลงที่ต้องการ "__RequestVerificationToken" ไม่มีอยู่

ฉันจะแก้ไขสิ่งนี้ได้อย่างไร

คำตอบ:


218

คุณมี[ValidateAntiForgeryToken]คุณสมบัติก่อนดำเนินการ คุณควรเพิ่ม@Html.AntiForgeryToken()ในแบบฟอร์มของคุณ


11
ฉันมีหน้าเว็บที่มีปัญหาเดียวกัน แต่ทุกสิ่งถูกต้อง ความผิดพลาดคืออะไร
ConductedClever

@ConductedClever คุณควรตรวจสอบทุกอย่าง (ฟิลด์คุกกี้) ด้วยพู้ทำเล่นและ / หรือ firebug (เครื่องมือ dev ของเบราว์เซอร์ใด ๆ ) ดูที่บทความนี้: asp.net/web-api/overview/security/ …
webdeveloper

@ ConductedClever ฉันด้วย นั่นเป็นงาน แต่ไม่ค่อยได้รับข้อผิดพลาดนี้และฉันไม่มีความคิดอะไรเลยทำไม?
QMaster

ฉันมีทุกอย่างโอเคในการทดสอบของฉันใช้งานได้บนเครื่องของลูกค้ามันใช้งานได้จนกระทั่งเมื่อไม่นานมานี้ แต่ตอนนี้มันทำให้เกิดข้อผิดพลาดนี้ ฉันมีความคิดว่าทำไมไม่มี. ใครมีแนวคิดอื่นนอกเหนือจากที่ระบุไว้ที่นี่
Andrei Dobrin

1
Html.AntiForgeryToken();ไม่ทำงาน, ไม่เป็นผล !! กลายเป็น@Html.AntiForgeryToken()งาน
FindOutIslamNow

78

ในกรณีของฉันฉันมีสิ่งนี้ในเว็บของฉัน config:

<httpCookies requireSSL="true" />

แต่โครงการของฉันถูกตั้งค่าให้ไม่ใช้ SSL การใส่ความคิดเห็นให้กับบรรทัดนั้นหรือการตั้งค่าโปรเจ็กต์ให้ใช้ SSL เสมอ


3
ในกรณีของฉัน web.config จำเป็นต้องใช้ SSL แต่มีการผูก IIS สำหรับทั้งพอร์ต 80 และ 443 ดังนั้นผู้ใช้ที่พิมพ์ https จะได้รับพฤติกรรมที่ถูกต้องและผู้ใช้ที่พิมพ์ http ได้รับข้อผิดพลาดนี้โดยวางกฎการเขียนซ้ำใหม่ / {HTTP_HOST} / {R: 1} แก้ไข
user1069816

ขอบคุณ😃ในกรณีของฉันIISมีข้อผูกมัดนี้ ( https » EmptyHostName » IP » 443) แต่ไม่มีข้อผูกมัดสำหรับ ( https » www.mysite.com » IP » 443) ดังนั้นฉันจึงเพิ่มการเชื่อมโยงใหม่ด้วยชื่อโฮสต์ที่ไม่ว่างเปล่าสำหรับhttpsสิ่งนั้นเท่ากับโดเมนและมันแก้ปัญหาได้ ฉันมีการตั้งค่าใหม่IISเพื่อบังคับใช้http 2 httpsเช่นกัน
RAM

61

แบบนี้:

ผู้ควบคุม

[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult MethodName(FormCollection formCollection)
{
     ...
     Code Block
     ...
}

มุมมอง:

@using(Html.BeginForm())
{
     @Html.AntiForgeryToken()
     <input name="..." type="text" />
     // rest
}

ลองใช้เฉพาะใน HTML
Subrata Sarkar

41

อย่าลืมใช้ [ValidateAntiForgeryToken] ใต้ [HttpGet]

  [HttpGet]
  public ActionResult MethodName()
  {
  ..
  }

1
คำตอบนี้ช่วยผู้อื่นและแก้ไขปัญหาของฉัน! ขอบคุณ
ลูคัส

1
คำตอบนี้ถือว่าคุณไม่ได้บันทึกข้อมูลใด ๆ ที่ส่งมา (ซึ่งคุณไม่ควรอยู่ใน HttpGet) หากคุณเป็นเช่นนั้นคุณยังต้องการการป้องกัน XSRF ที่ [ValidateAntiForgeryToken] ให้ไว้
thelem

9

คุณจะได้รับข้อผิดพลาดแม้ว่าจะไม่ได้เปิดใช้งานคุกกี้


2
ยอดเยี่ยม ฉันใช้ Internet Explorer การใช้เบราว์เซอร์ Chrome แก้ไขปัญหาให้ฉัน
FindOutIslamNow

นี่เป็นการแก้ไขปัญหาของฉันด้วย เปิดใช้งานคุกกี้ใน google chrome ขอบคุณ
วิธีการทางวิทยาศาสตร์

7

อีกสิ่งหนึ่งที่ทำให้เกิดปัญหานี้ (เพิ่งพบเจอ) คือสิ่งต่อไปนี้หากคุณปิดใช้งานฟิลด์ป้อนข้อมูลทั้งหมดในแบบฟอร์มของคุณด้วยเหตุผลบางประการ มันจะปิดการใช้งานช่องใส่ที่ซ่อนอยู่ที่เก็บโทเค็นการตรวจสอบของคุณ เมื่อแบบฟอร์มจะถูกโพสต์กลับค่าโทเค็นจะหายไปและจะสร้างข้อผิดพลาดว่ามันหายไป ดังนั้นสิ่งที่คุณต้องทำคือเปิดใช้งานช่องป้อนข้อมูลที่เก็บโทเค็นการตรวจสอบอีกครั้งและทุกอย่างจะดี


6

ความเป็นไปได้อีกประการหนึ่งสำหรับพวกเราที่อัปโหลดไฟล์เป็นส่วนหนึ่งของคำขอ หากความยาวของเนื้อหาเกิน<httpRuntime maxRequestLength="size in kilo bytes" /> และคุณใช้โทเค็นการตรวจสอบคำขอเบราว์เซอร์จะแสดง'The required anti-forgery form field "__RequestVerificationToken" is not present'ข้อความแทนข้อความที่เกินความยาวที่ร้องขอ

การตั้งค่า maxRequestLength ให้เป็นค่าที่มากพอที่จะรองรับการร้องขอให้แก้ไขปัญหาได้ทันที - แม้ว่าฉันจะยอมรับว่ามันไม่ใช่วิธีการแก้ปัญหาที่เหมาะสม (เราต้องการให้ผู้ใช้ทราบถึงปัญหาที่แท้จริงของขนาดไฟล์


5

ตรวจสอบให้แน่ใจในคอนโทรลเลอร์ของคุณว่าคุณมีแอตทริบิวต์ http ของคุณเช่น:

[HttpPost]

เพิ่มแอตทริบิวต์ในคอนโทรลเลอร์ด้วย:

[ValidateAntiForgeryToken]

ในแบบฟอร์มของคุณในมุมมองของคุณคุณต้องเขียน:

@Html.AntiForgeryToken();

ฉันมี Html.AntiForgeryToken (); โดยไม่ต้องมีเครื่องหมาย @ ในขณะที่อยู่ในบล็อกรหัสมันไม่ได้ให้ข้อผิดพลาดใน Razor แต่เกิดขึ้นในขณะทำงาน ตรวจสอบให้แน่ใจว่าคุณดูที่เครื่องหมาย @ ของ @ Html.Ant .. หากมันหายไปหรือไม่


5

ในกรณีของฉันฉันมี javascript นี้ในแบบฟอร์มส่ง:

$('form').submit(function () {
    $('input').prop('disabled', true);
});

นี่เป็นการลบ RequestVerificationToken จากแบบฟอร์มที่กำลังส่ง ฉันเปลี่ยนเป็น:

$('form').submit(function () {
    $('input[type=submit]').prop('disabled', true);
    $('input[type=text]').prop('readonly', true);
    $('input[type=password]').prop('readonly', true);
});

... และมันก็ใช้ได้ดี


คุณสังเกตเห็นได้อย่างไรว่าปุ่มป้องกันได้รับผลกระทบเมื่อคุณปิดใช้งานอินพุต
Cer

1
@Cer - หากคุณถามว่าฉันสังเกตเห็นฉันตรวจสอบคำขอด้วยพู้ทำเล่นและรับว่ากุญแจไม่ได้ถูกส่ง ฉันอ่านแล้วว่าการส่ง Html จะไม่รวมการควบคุมที่ถูกปิดใช้งาน ดังนั้นฉันจึงเปลี่ยนเป็นreadonlyและยกเว้นการควบคุมที่ซ่อนอยู่ ดูเหมือนว่าจะทำงานอย่างดี
Sean

3

หากใครก็ตามพบข้อผิดพลาดด้วยเหตุผลเดียวกันกับที่ฉันพบนี่คือวิธีแก้ปัญหาของฉัน:

ถ้าคุณมี Html.AntiForgeryToken();

เปลี่ยนเป็น @Html.AntiForgeryToken()


2

ในกรณีของฉันโดเมนไม่ถูกต้องใน web.config สำหรับคุกกี้คือเหตุผล:

<httpCookies domain=".wrong.domain.com" />

yeep! หากคุณใช้คอมพิวเตอร์ในระบบ <httpCookies domain = "localhost" /> จะทำงานเฉพาะกับคุกกี้คอมพิวเตอร์ในพื้นที่เท่านั้นและหากคุณพยายามเปิดเว็บไซต์ของคุณบนเครื่องอื่นคุณจะต้องป้อน ip (fe 192.168.1.43) ซึ่งจะไม่ทำงานเพราะ มันกำลังมองหา "localhost"
user3419036

2

ในกรณีของฉันมันเป็นเพราะการเพิ่มrequireSSL=trueการhttpcookiesใน webconfig ซึ่งทำให้หยุดการทำงาน AntiForgeryToken ตัวอย่าง:

<system.web>
  <httpCookies httpOnlyCookies="true" requireSSL="true"/>
</system.web>

เพื่อให้ทั้งสองrequireSSL=trueและการ@Html.AntiForgeryToken()ทำงานฉันเพิ่มบรรทัดนี้ภายในApplication_BeginRequestในGlobal.asax

    protected void Application_BeginRequest(object sender, EventArgs e)
  {
    AntiForgeryConfig.RequireSsl = HttpContext.Current.Request.IsSecureConnection;
  }

2

มีข้อผิดพลาดนี้ใน Chrome ด้วยการเข้าสู่ระบบเริ่มต้นสำหรับ ASP.NET ด้วยบัญชีผู้ใช้ส่วนบุคคล

.cshtml:

@using (Html.BeginForm("Login", "Account", new { ReturnUrl = ViewBag.ReturnUrl }, FormMethod.Post, new { @class = "form-horizontal", role = "form" }))
{
    @Html.AntiForgeryToken()
    <h4>Use a local account to log in.</h4>

ควบคุม:

[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Login(LoginViewModel model, string returnUrl)

แก้ไขโดยล้างข้อมูลไซต์สำหรับไซต์:

ป้อนคำอธิบายรูปภาพที่นี่


ตกลงมันทำงาน แต่สิ่งนี้เกิดขึ้นซ้ำแล้วซ้ำอีก ใน Firefox โครงการเดียวกันทำงานอย่างถูกต้อง ฉันจะทำอย่างไร
สามารถทำลาย

@ CanÜrekคุณมีหลายโครงการ / เว็บไซต์ที่มีโดเมนเดียวกันหรือไม่? ไม่ว่าจะเป็น localhost, app.site.com และ app2.site.com เป็นต้น ปกติแล้วมันจะเกิดขึ้นเพราะสิ่งนี้
Ogglas

0

ในโซลูชัน EPiServer ของฉันบนตัวควบคุมหลายตัวมีแอตทริบิวต์ ContentOutputCache ในการดำเนินการดัชนีซึ่งยอมรับ HttpGet แต่ละมุมมองสำหรับการกระทำเหล่านั้นมีแบบฟอร์มที่โพสต์ไปยังการดำเนินการ HttpPost ไปยังตัวควบคุมเดียวกันหรือไปที่มุมมองอื่น ทันทีที่ฉันลบแอตทริบิวต์นั้นออกจากปัญหาการกระทำดัชนีเหล่านั้นก็หายไป


0

เพราะสิ่งนี้เกิดขึ้นกับการค้นหาครั้งแรกของสิ่งนี้:

ฉันมีปัญหานี้ใน Internet Explorer เท่านั้นและไม่สามารถเข้าใจได้ว่าปัญหาคืออะไร เรื่องสั้นสั้น ๆ มันไม่ได้บันทึกส่วนคุกกี้ของโทเค็นเนื่องจากโดเมน (ย่อย) ของเรามีขีดเส้นใต้อยู่ ทำงานใน Chrome แต่ IE / Edge ไม่ชอบ


0

คำตอบอื่น ๆ ทั้งหมดในที่นี้ก็ใช้ได้เช่นกัน แต่ถ้าไม่มีคำตอบใด ๆ ที่แก้ไขปัญหานี้ก็ควรตรวจสอบด้วยว่าส่วนหัวจริงถูกส่งผ่านไปยังเซิร์ฟเวอร์หรือไม่

ตัวอย่างเช่นในสภาพแวดล้อมที่สมดุลโหลดหลัง nginx การกำหนดค่าเริ่มต้นคือการแยกส่วนหัว __RequestVerificationTokenก่อนที่จะผ่านการร้องขอไปยังเซิร์ฟเวอร์ดู: ง่าย ๆ nginx reverse proxy ดูเหมือนว่าจะดึงหัวบางส่วน


0

บางครั้งคุณกำลังเขียนวิธีการดำเนินการแบบฟอร์มด้วยรายการผลลัพธ์ ในกรณีนี้คุณไม่สามารถทำงานกับวิธีการหนึ่งวิธี ดังนั้นคุณต้องมีวิธีการสองวิธีในชื่อเดียวกัน หนึ่งกับ[HttpGet]อีกและมี[HttpPost]คุณสมบัติ

ใน[HttpPost]วิธีการกระทำของคุณให้ตั้งค่า[ValidateAntiForgeryToken]คุณสมบัติและใส่@Html.AntiForgeryToken()ในรูปแบบ html ของคุณ


0

ในกรณีของฉันฉันได้รับข้อผิดพลาดนี้ขณะทำการโพสต์ AJAX มันกลับกลายเป็นว่าค่า __RequestVerificationToken ไม่ได้ถูกส่งผ่านในการโทร ฉันต้องค้นหาค่าของฟิลด์นี้ด้วยตนเองและตั้งค่านี้เป็นคุณสมบัติบนวัตถุข้อมูลที่ส่งไปยังจุดสิ้นสุด

กล่าวคือ data.__RequestVerificationToken = $('input[name="__RequestVerificationToken"]').val();


ตัวอย่าง

HTML

  <form id="myForm">
    @Html.AntiForgeryToken()

    <!-- other input fields -->

    <input type="submit" class="submitButton" value="Submit" />
  </form>

จาวาสคริ

$(document).on('click', '#myForm .submitButton', function () {
  var myData = { ... };
  myData.__RequestVerificationToken = $('#myForm input[name="__RequestVerificationToken"]').val();

  $.ajax({
    type: 'POST',
    url: myUrl,
    data: myData,
    contentType: 'application/x-www-form-urlencoded; charset=utf-8',
    dataType: 'json',
    success: function (response) {
      alert('Form submitted');
    },
    error: function (e) {
      console.error('Error submitting form', e);
      alert('Error submitting form');
    },
  });
  return false; //prevent form reload
});

ตัวควบคุม

    [HttpPost]
    [Route("myUrl")]
    [ValidateAntiForgeryToken]
    public async Task<ActionResult> MyUrlAsync(MyDto dto)
    {
        ...
    }

อันที่จริงถ้าคุณจะกำหนดโครงสร้างของคลาส MyDto ของคุณมันจะมีประโยชน์มาก
Chandan Kumar

ฉันไม่แน่ใจว่ามันจะมีประโยชน์มากจริง ๆ และตัวอย่างโค้ดหายไปนานแล้วสมมุติว่าpublic class MyDto { public bool Whatever { get; set; } }
demoncodemonkey

-1

ฉันต้องการที่จะแบ่งปันของฉันฉันได้รับการติดตามการกวดวิชาต่อต้านการปลอมแปลงนี้ ใช้ asp.net mvc 4 กับ angularjs แต่มันก็มีข้อยกเว้นทุกครั้งที่ฉันขอใช้ $ http.post และฉันคิดวิธีแก้ปัญหาก็แค่เพิ่ม 'X-คำขอ- ด้วย ':' XMLHttpRequest 'ที่ส่วนหัวของ $ http.post เนื่องจากดูเหมือนว่า(filterContext.HttpContext.Request.IsAjaxRequest()) จะไม่รู้จักว่าเป็น ajax และนี่คือรหัสตัวอย่างของฉัน

App.js

var headers = { 'X-Requested-With': 'XMLHttpRequest', 'RequestVerificationToken': $scope.token, 'Content-Type': 'application/json; charset=utf-8;' };

$http({ method: 'POST', url: baseURL + 'Save/User', data: JSON.stringify($scope.formData), headers: headers }).then(function (values) { alert(values.data); }).catch(function (err) { console.log(err.data); });


SaveController

[HttpPost] [MyValidateAntiForgeryToken] public ActionResult User(UserModel usermodel) { ....

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.