2012-01-27 11 views
10

私はOrchard 1.3.10サイトでテストしているOrchard CMSモジュールを構築しています。このモジュールは、エンティティの1つの詳細ビューを表示し、「お気に入り」ボタンをクリックして、コントローラアクションのajaxポストを実行して、データベース内のお気に入りとしてエンティティを保存します。ログインしたOrchard CMS Ajax偽造トークン

私は、次のコードを持っているビューの場合:私はちょうど戻って、オーチャードにログインせずにこのコードの記事をサイトを実行すると

<div style="padding: 10px;"> 
    <span data-id="@Model.Id" id="addFavorite" style="cursor: pointer;"> 
    [Add Favorite] 
    </span> 
</div> 

<script type="text/javascript"> 
    $("#addFavorite").click(function() { 
     alert("here we go..."); 
     $.ajax({ 
      type: "post", 
      dataType: "", 
      url: "/orchardlocal/mymodule/stuff/AddFavorite", 
      data: { id: $(this).data("id") }, 
      success: function (response) { 
       alert("it worked"); 
      } 
     }); 
    }); 
</script> 

私のコントローラのアクションが...

[HttpPost] 
public ActionResult AddFavorite(int id) 
{ 
    return View(); 
} 

です良い。ログインしてお気に入りをクリックすると、この例外が発生します。

必須の偽造トークンが提供されていないか無効です。

System.Web.Mvc.HttpAntiForgeryExceptionがユーザーコード によって処理されませんでした。メッセージ=必要な偽造防止トークンが提供されなかったか、無効でした。 ソース= System.Web.WebPages のErrorCode = -2147467259 WebEventCode = 0 のStackTrace:System.Web.Helpers.AntiForgeryWorker.Validate(HttpContextBaseコンテキスト、文字列の塩)で System.Web.Helpers.AntiForgery.Validateで( HttpContextBaseのHttpContext、文字列の塩)System.Web.Mvc.ValidateAntiForgeryTokenAttribute.OnAuthorization(AuthorizationContext> filterContextで )Orchard.Mvc.AntiForgery.AntiForgeryAuthorizationFilter.OnAuthorization(AuthorizationContext filterContext)で Cで:\コード\ OrchardDev2 \ SRC \オーチャード\ MVC \ AntiForgery \ AntiForgeryAuthorizationFilter.cs:Line 37 at System.Web.Mvc.ControllerActionInvoker.InvokeAuthorizationFilters(ControllerContext controllerContext、IList`1フィルタ、ActionDescriptor a System.Web.Mvc.ControllerActionInvoker.InvokeAction(ControllerContext controllerContext、文字列actionNameのでctionDescriptor) ) のInnerException:

なぜそれがログインしたときに、異なるポストを治療していないのですか?

これを避けるにはどうすれば偽造防止トークンを提供できますか?私はこれを回避するために、抗偽造トークンを供給することができますどのように

おかげで、 ブライアン

答えて

23

ASP.NET MVCでは、デフォルトで生の偽造防止トークンの生成はサポートされていません。幸いにも、オーチャードはそのための拡張方法を提供しています。

あるとしてあなたは、単にあなたのAJAX呼び出しを変更することができます。

$.ajax({ 
    type: "post", 
    dataType: "", 
    url: "/orchardlocal/mymodule/stuff/AddFavorite", 
    data: { 
     id: $(this).data("id") }, 
     __RequestVerificationToken: '@Html.AntiForgeryTokenValueOrchard()' 
    }, 
    success: function (response) { 
     alert("it worked"); 
    } 
}); 

あなたのページ上の既存のフォームを必要としないため、この技術が有用です。このソリューションは、javascriptがRazorビューからレンダリングされる場合にのみ有効です。

@using(Script.Head()) { 
<script type="text/javascript"> 
//<![CDATA[ 
    var antiForgeryToken = '@Html.AntiForgeryTokenValueOrchard()'; 
//]]> 
</script> 
} 
:あなたは、ビューから宣言javascriptの変数内の偽造防止トークンを保存するスクリプトから、それを使用することで、あなたのビューから別のスクリプトファイルを持っている場合

はまだ解決策があります

そして、スクリプトから:

data: { 
    id: $(this).data("id") }, 
    __RequestVerificationToken: antiForgeryToken 
} 

ない場合は、ダーリンによって提案された解決策は、彼が正しいアプローチだろう。

+0

Sebastien、私は、__RequestVerificationTokenがデータ{}の内部にあるべきであるという誤植があると思いますか?また、@ Html.AntiForgeryTokenValueOrchard()をjavascriptに追加すると、「条件付きコンパイルがオフになっています」と言って、VSに派手な行が表示されています。私はこれがRazorのバグであると述べている別の記事を読んだが、これを行うべきである... @(Html.AntiForgeryTokenValueOrchard())。しかし、私はこれを行うときに、JavaScriptエラー「構文エラー4」が発生しています。他に何が私はここで行方不明になることができる?ありがとう、ブライアン –

+0

私は回答を完了しました –

+0

セバスチャン、これは素晴らしい作品です。ありがとう! –

3

これは、偽造防止トークンを含む隠しフィールドがページ上にある場所によって異なります。例:

$("#addFavorite").click(function() { 
    var token = $(':input[name="__RequestVerificationToken"]').val(); 
    $.ajax({ 
     type: "post", 
     dataType: "", 
     url: "/orchardlocal/mymodule/stuff/AddFavorite", 
     data: { 
      __RequestVerificationToken: token, 
      id: $(this).data("id") 
     }, 
     success: function (response) { 
      alert("it worked"); 
     } 
    }); 
});