2013-04-05 17 views
32

私のSPAの一部の領域をすべてのユーザーに開放する必要があり、一部の領域には認証が必要です。これらの領域では、AJAXを介してロードされる、保護したいデータです。Durandal SPAテンプレートを使用したMVC認証および偽造防止トークン

私は認証サービス(下記参照)を持っています。これは私のdurandalに依存するものとして追加しますmain.js。サービスが呼び出されます。私のmain.js

authentication 

私はそれは、彼らが許可されていないユーザーに警告し、彼らは入ることができ、ログインビュー/のviewmodelにユーザーをナビゲート

authentication.handleUnauthorizedAjaxRequest(function() { 
     app.showMessage('You are not authorized, please login') 
     .then(function() { 
      router.navigateTo('#/user/login'); 
     }); 
    }); 

を呼び出します詳細は、とにログインしてみてください

この認証のViewModel構築するときに頭に浮かぶいくつかの質問:。

  • 私がやっていることに明らかな懸念はありますか?
  • これは私がDurandalで何かを行うことを意味するのでしょうか?
  • ホイールを再発明していますか?私はDurandal内でこのようなことは何も見えませんでした。

ほとんどの人は、別々に作成しているようです。cshtmlページ。 1つはログイン用です(ユーザーが認証されていない場合)。通常はindex.cshtmlこの方法に切り替える理由はありますか?

私のサーバー側の「ユーザーコントローラー」のログインアクションには、[ValidateAntiForgeryToken]属性があります。この属性も送信する必要があります。
私はまた、私の依存関係として私のmain.js viewModelファイル (私のmain.js内)にも追加する '偽造防止サービス'(下記参照)を持っています。

antiforgery.addAntiForgeryTokenToAjaxRequests(); 

これは(コンテンツとともに)すべてのajaxリクエストをインターセプトし、MVC AntiForgeryToken値をデータに追加します。 私が望むのとまったく同じように動作するようです。エラーや間違いがあれば教えてください。

下記の完全な認証サービス。

// services/authentication.js 
define(function (require) { 
    var system = require('durandal/system'), 
    app = require('durandal/app'), 
    router = require('durandal/plugins/router'); 

    return { 
     handleUnauthorizedAjaxRequests: function (callback) { 
      if (!callback) { 
       return; 
      } 
      $(document).ajaxError(function (event, request, options) { 
       if (request.status === 401) { 
        callback(); 
       } 
      }); 
     }, 

     canLogin: function() {   
      return true; 
     }, 
     login: function (userInfo, navigateToUrl) { 
      if (!this.canLogin()) { 
       return system.defer(function (dfd) { 
        dfd.reject(); 
       }).promise(); 
      } 
      var jqxhr = $.post("/user/login", userInfo) 
       .done(function (data) { 
        if (data.success == true) { 
         if (!!navigateToUrl) { 
          router.navigateTo(navigateToUrl); 
         } else { 
          return true; 
         } 
        } else { 
         return data; 
        } 
       }) 
       .fail(function (data) { 
        return data; 
       }); 

      return jqxhr; 
     } 
    }; 
}); 

// services/antiforgery.js 
define(function (require) { 
    var app = require('durandal/app'); 

    return { 
     /* this intercepts all ajax requests (with content) 
      and adds the MVC AntiForgeryToken value to the data 
      so that your controller actions with the [ValidateAntiForgeryToken] attribute won't fail 

      original idea came from http://stackoverflow.com/questions/4074199/jquery-ajax-calls-and-the-html-antiforgerytoken 

      to use this 

      1) ensure that the following is added to your Durandal Index.cshml 
      <form id="__AjaxAntiForgeryForm" action="#" method="post"> 
       @Html.AntiForgeryToken() 
      </form> 

      2) in main.js ensure that this module is added as a dependency 

      3) in main.js add the following line 
      antiforgery.addAntiForgeryTokenToAjaxRequests(); 

     */ 
     addAntiForgeryTokenToAjaxRequests: function() { 
      var token = $('#__AjaxAntiForgeryForm  input[name=__RequestVerificationToken]').val(); 
      if (!token) { 
       app.showMessage('ERROR: Authentication Service could not find  __RequestVerificationToken'); 
      } 
      var tokenParam = "__RequestVerificationToken=" + encodeURIComponent(token); 

      $(document).ajaxSend(function (event, request, options) { 
       if (options.hasContent) { 
        options.data = options.data ? [options.data, tokenParam].join("&") :  tokenParam; 
       } 
      }); 
     } 

    }; 
}); 
+0

こんにちはStuart、 あなたのアイデアは素晴らしいです。私はHot Towel/Durandalプロジェクトでそれを適用しようとしています。私は認証と偽造防止サービスを手に入れましたが、承認されていないユーザーを傍受してログインページにリダイレクトする認証サービスはありません。それ、どうやったら出来るの? Index.cshtmlに何かを追加する必要がありますか? ありがとう –

+0

これはDurandalJs Googleグループにもあります。そこには他の人からの更新があり、いくつかのコード例も追加されています。コメントはここには収まりません。リンクhttps://groups.google.com/forum/?hl=ja&fromgroups=#!topic/durandaljs/iq9OPprfob0 – stooboo

答えて

14

私は、ヘッダーに偽造防止トークンを渡すことをお勧めします。この方法は、フォームのデータと混ざらないため、サーバー上の要求から簡単に解析できます。

次に、カスタムアクションフィルタを作成して、偽造防止トークンを確認しました。

I created a post既にこれを行う方法について。

+0

+1いいアイデアは、それのための有効な場所のように聞こえる! – mikekidder

+0

乾杯エヴァン、私はヘッダーを入れることについて考えていませんでした(私はあなたの投稿を見なかったのでリンクのおかげで) – stooboo

関連する問題