2013-04-05 6 views
32

मेरे एसपीए के कुछ क्षेत्रों को सभी उपयोगकर्ताओं के लिए खुला होना चाहिए, और कुछ क्षेत्रों को प्रमाणीकरण की आवश्यकता है। इन क्षेत्रों में, यह AJAX के माध्यम से लोड किया गया डेटा है जिसे मैं संरक्षित करना चाहता हूं।एमवीसी प्रमाणीकरण और एंटीफोर्गेरी टोकन डुरंडल एसपीए टेम्पलेट

मेरे पास एक प्रमाणीकरण सेवा है (नीचे देखें), जिसे मैं अपने डुरंडल main.js में निर्भरता के रूप में जोड़ता हूं। सेवा कहा जाता है:

authentication 

मेरी main.js मैं फोन

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

यह उपयोगकर्ता वे अधिकृत नहीं हैं चेतावनी देते हैं, और एक लॉगिन देखें/viewmodel जहां वे प्रवेश कर सकते हैं करने के लिए उपयोगकर्ता नेविगेट करता है में विवरण और प्रवेश करने का प्रयास

कुछ सवाल जब इस प्रमाणीकरण ViewModel निर्माण जो मन में आते हैं:।

  • क्या मैं कर रहा हूं इसके साथ कोई स्पष्ट चिंता है?
  • क्या यह दुरंदल में चीजों को करने के लिए 'मतलब' है?
  • क्या मैं पहिया का पुन: आविष्कार कर रहा हूं? मैं डुरंडल के भीतर ऐसा कुछ नहीं देख सका।

अधिकांश लोग अलग-अलग cshtml पृष्ठों को बना रहे हैं; लॉगिन के लिए एक (यदि उपयोगकर्ता प्रमाणीकृत नहीं है), और सामान्य index.cshtml क्या इस विधि पर स्विच करने के लिए मेरे कोई अच्छे कारण हैं?

मेरे सर्वर-साइड 'उपयोगकर्ता नियंत्रक' पर मेरी लॉगिन कार्रवाई में [ValidateAntiForgeryToken] विशेषता है जिसे मुझे भी भेजने की आवश्यकता है।
मेरे पास एक 'एंटीफॉर्गेरी' सेवा भी है (नीचे देखें) जो मैं अपने main.js व्यूमोडेल फ़ाइल पर भी निर्भरता के रूप में जोड़ता हूं (फिर भी मेरे 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

हाय स्टुअर्ट, आपका विचार बहुत अच्छा है, और मैं इसे अपने हॉट टॉवेल/डुरंडल प्रोजेक्ट में लागू करने की कोशिश कर रहा हूं। मुझे ऑथ और एंटीफोर्गेरी सेवाएं मिलीं, लेकिन मुझे अनधिकृत उपयोगकर्ताओं को रोकने और लॉगिन पेज पर रीडायरेक्ट करने के लिए ऑथ सेवा नहीं मिल रही है। मैं उसको कैसे करू? क्या मुझे index.cshtml में कुछ जोड़ने की ज़रूरत है? धन्यवाद –

+0

यह DurandalJs Google समूह पर भी है - वहां अन्य लोगों के अपडेट भी हैं और मैंने कुछ कोड उदाहरण भी जोड़े हैं - वे वास्तव में यहां एक टिप्पणी में फिट नहीं होंगे ... तो ;-) .. यहाँ है लिंक https://groups.google.com/forum/?hl=hi&fromgroups=#!topic/durandaljs/iq9OPprfob0 – stooboo

उत्तर

14

मैं हेडर में एंटीफॉर्गेरी टोकन पास करना पसंद करता हूं। इस तरह सर्वर पर अनुरोध से बाहर निकलना आसान है क्योंकि यह आपके फॉर्म के डेटा से जुड़ा हुआ नहीं है।

मैंने फिर एंटीफोर्गेरी टोकन की जांच के लिए एक कस्टम एक्शन फ़िल्टर बनाया।

I created a post पहले से ही यह कैसे करें।

+0

+1 अच्छा विचार, इसके लिए एक वैध स्थान की तरह लगता है! – mikekidder

+0

चीयर्स इवान, मैंने हेडर में डालने के बारे में सोचा नहीं था (मैंने आपकी पोस्ट को लिंक के लिए धन्यवाद नहीं देखा था) – stooboo

संबंधित मुद्दे