Некоторые области моего SPA должны быть открыты для всех пользователей, а некоторые области требуют аутентификации. В этих областях это данные, загруженные через AJAX, которые я хочу защитить.Знак аутентификации и антикоррозионной аутентификации MVC с шаблоном SPA Durandal
У меня есть служба аутентификации (см. Ниже), которую я добавляю в качестве зависимости в моем durandal 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 pages; один для входа в систему (если пользователь не аутентифицирован) и обычный index.cshtml Есть ли веские причины для переключения на этот метод?
Мое действие для входа на мой пользовательский контроллер на стороне сервера имеет атрибут [ValidateAntiForgeryToken], который мне также нужно отправить.
У меня также есть услуга «antiforgery» (см. Ниже), которую я также добавляю в качестве зависимости в моем main.js viewModel file then (также в моем 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;
}
});
}
};
});
Hi Stuart, Ваша идея замечательная, и я пытаюсь применить ее в своем проекте Hot Towel/Durandal. Я получил услуги auth и antiforgery, но я не получаю auth-сервис, чтобы перехватить неавторизованных пользователей и перенаправить их на страницу входа. Как мне это сделать? мне нужно добавить что-то в Index.cshtml? Спасибо –
Это также на DurandalJs Google Group - там были обновления от других людей, и я также добавил некоторые примеры кода - они не будут вписываться в комментарий здесь ... так ;-) .. вот ссылка https://groups.google.com/forum/?hl=ru&fromgroups=#!topic/durandaljs/iq9OPprfob0 – stooboo