Note that there are some explanatory texts on larger screens.

plurals
  1. POMVC Authentication and Antiforgery token with Durandal SPA template
    primarykey
    data
    text
    <p>Some areas of my SPA need to be open to all users, and some areas require authentication. In these areas, it's the data loaded via AJAX that I want to protect.</p> <p>I have an authentication service (see below), which I add as a dependency in my durandal <strong>main.js</strong>. The service is called:</p> <pre><code>authentication </code></pre> <p>In my <strong>main.js</strong> I call</p> <pre><code>authentication.handleUnauthorizedAjaxRequest(function () { app.showMessage('You are not authorized, please login') .then(function () { router.navigateTo('#/user/login'); }); }); </code></pre> <p>It warns the user they are not authorized, and navigates user to a login view/viewmodel where they can enter details and try logging in. </p> <p>Some questions that come to mind when building this authentication viewModel:</p> <ul> <li>Are there any obvious concerns with what I'm doing?</li> <li>Is this how I'm 'meant' to do things in Durandal?</li> <li>Am I re-inventing the wheel? I couldn't see anything like this within Durandal.</li> </ul> <p>Most people seem to be creating seperate <strong>cshtml</strong> pages; one for login (if the user is not authenticated), and the usual <strong>index.cshtml</strong> Is there any good reasons for me to switch to that method?</p> <p>My login action on my the server-side 'user controller' has the [ValidateAntiForgeryToken] attribute I need to send that as well.<br> I also have an 'antiforgery' service (see below) which I also add as a dependency in my <strong>main.js</strong> viewModel file then (also in my main.js).</p> <pre><code>antiforgery.addAntiForgeryTokenToAjaxRequests(); </code></pre> <p>This intercepts all ajax requests (along with content), and adds the MVC AntiForgeryToken value to the data. Seems to work exactly as I want it to. Please let me know if there's any errors/mistakes.</p> <p>Complete authentication service below.</p> <pre><code>// 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 &lt;form id="__AjaxAntiForgeryForm" action="#" method="post"&gt; @Html.AntiForgeryToken() &lt;/form&gt; 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("&amp;") : tokenParam; } }); } }; }); </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload