Alcune aree della SPA devono essere aperte a tutti gli utenti e alcune aree richiedono l'autenticazione. In queste aree, sono i dati caricati tramite AJAX che voglio proteggere.Token di autenticazione MVC e antifora con modello Durandal SPA
Ho un servizio di autenticazione (vedi sotto), che aggiungo come dipendenza nel mio dur.. Il servizio si chiama:
authentication
Nei miei main.js io chiamo
authentication.handleUnauthorizedAjaxRequest(function() {
app.showMessage('You are not authorized, please login')
.then(function() {
router.navigateTo('#/user/login');
});
});
Si avverte l'utente che non sono autorizzati, e naviga utente ad una vista di login/viewmodel dove possono entrare dettagli e prova ad accedere
Alcune domande che vengono in mente quando si costruisce questa autenticazione ViewModel:.
- Ci sono ovvi problemi con quello che sto facendo?
- È così che sono "intenzionato" a fare cose a Durandal?
- Sto reinventando la ruota? Non potevo vedere nulla di simile in Durandal.
La maggior parte delle persone sembra creare pagine separate cshtml; uno per login (se l'utente non è autenticato), e il solito index.cshtml Ci sono dei buoni motivi per passare a quel metodo?
La mia azione di accesso sul mio 'controller utente' lato server ha l'attributo [ValidateAntiForgeryToken] che devo inviare anche a questo.
Ho anche un servizio di "antiforgery" (vedi sotto) che aggiungo anche come dipendenza nel mio main.js viewModel file quindi (anche nel mio main.js).
antiforgery.addAntiForgeryTokenToAjaxRequests();
Questo intercetta tutte le richieste Ajax (insieme con il contenuto), e aggiunge il valore di MVC AntiForgeryToken ai dati. Sembra funzionare esattamente come voglio. Per favore fatemi sapere se ci sono errori/errori.
Completo servizio di autenticazione di seguito.
// 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;
}
});
}
};
});
Hi Stuart, La tua idea è ottima e sto cercando di applicarla nel mio progetto Hot Towel/Durandal. Ho ottenuto i servizi auth e antiforgery, ma non sto ottenendo il servizio auth per intercettare utenti non autorizzati e reindirizzarli alla pagina di accesso. Come lo faccio? devo aggiungere qualcosa a Index.cshtml? Grazie –
Questo è anche sul gruppo Google di DurandalJs - ci sono stati aggiornamenti da altre persone e ho anche aggiunto alcuni esempi di codice - non saranno davvero adatti a un commento qui ... quindi ;-) .. ecco il link https://groups.google.com/forum/?hl=it&fromgroups=#!topic/durandaljs/iq9OPprfob0 – stooboo