Шаблоны для безопасности JavaScript с внутренней авторизацией? - PullRequest
26 голосов
/ 15 ноября 2011

Я ищу несколько хороших ресурсов, шаблонов и практических приемов для решения основных задач безопасности, таких как авторизация, в клиентском JavaScript.

Я создаю веб-сайт с серверной системой, на которой работает одна из распространенных сред MVC.Серверная часть будет обрабатывать все реальные потребности безопасности: авторизацию и аутентификацию.Фронт будет построен с Backbone.js, jQuery и несколькими другими библиотеками, чтобы облегчить очень богатый пользовательский опыт.

Вот пример одного сценария, который мне нужно обработать:

Iиметь сетку данных с несколькими кнопками поверх него.Если вы выберете элемент в сетке, некоторые кнопки станут активными, чтобы вы могли выполнить это действие для выбранного элемента.Эту функциональность легко построить ...

Теперь мне нужно рассмотреть вопрос авторизации.Внутренний сервер будет отображать только те кнопки, с которыми пользователю разрешено работать.Кроме того, внутренний сервер проверяет авторизацию, когда пользователь пытается выполнить это действие.... так что серверная часть закрыта, и пользователь не сможет делать то, что он пытается, если он не авторизован.

Но как насчет JavaScript?Если мой код настроен с помощью набора обработчиков нажатий jQuery или других событий, которые включают и отключают кнопки, как мне обрабатывать кнопки, которых там нет?Я просто пишу кучу уродливых if операторов, проверяющих существование кнопки?Или я пишу JavaScript таким способом, который позволяет мне отправлять JavaScript только для существующих кнопок, вплоть до браузера, на основе авторизации?или ???

Теперь представьте себе древовидное представление, которое может или не может использовать функцию перетаскивания, основанную на авторизации ... и форму добавления / редактирования, которая может существовать или не существовать на основе авторизации ...и все эти другие сложные авторизационные потребности, с большим количеством JavaScript для запуска этих частей внешнего интерфейса.

Я ищу ресурсы, шаблоны и методы для обработки сценариев такого рода, где обрабатывает серверная частьреальное разрешение, но внешний интерфейс также должен учитывать вещи, которых там нет, на основании разрешения.

Ответы [ 7 ]

7 голосов
/ 16 ноября 2011

Я видел три довольно простых вещи:

  • Модульные просмотры магистрали Мне очень понравились вложенные и высокомодульные представления Backbone. То есть каждая строка в вашем дереве может быть представлением Backbone и реагировать на собственные требования авторизации.

  • Несколько хэшей событий Установите несколько хэшей событий в представлении, которое вы переключаете с помощью DelegateEvents () в соответствии с вашими требованиями авторизации и инициируемое событием. Таким образом вы обойдете множество уродливых операторов if.

  • Несколько шаблонов Аналогичным образом вы указываете несколько шаблонов для отображения на основе требований авторизации.

Всем трем потребовалась бы настроенная структура событий (например, с использованием вашего собственного обработчика vent PubSub), где вы запускаете проверки авторизации на основе ответа на запрос RESTful-сервера или на основе какой-либо функции на стороне клиента.

4 голосов
/ 15 ноября 2011

Способ обработки аутентификации на клиенте заключается в том, чтобы иметь одноэлементную модель Backbone, которая содержит значение isAuthenticated , которое я первоначально заполняю с сервера:

@{
  App.user.set({ isAuthenticated: @UserSession.IsAuthenticated.ToString().ToLower() });
}

Затем все javascriptэлементы управления / функциональные возможности, которые изменяют поведение на основе аутентификации, в основном просто слушают изменения в этом поле и повторно переводит в правильное состояние.Все это представление / логика выполняется с помощью JavaScript, поэтому он работает во время генерации страницы (сервером) или на клиенте с Javascript / ajax.

Я не поддерживаю обработчики событий для существующей / скрытой функциональности, я воссоздаю все элементы пользовательского интерфейса и заново подключаю все обработчики событий после повторной визуализации представлений на основе флага isAuthenticated.

Приятно то, что после входа в систему с помощью ajax на клиенте (т. Е. После рендеринга страницы сервера) вам просто нужно установить одно и то же поле, и как по волшебству (Backbone FTW :) все работает иоказывает правильно.

2 голосов
/ 16 ноября 2011

Я бы порекомендовал использовать шаблон Factory вместе со свойствами класса Backbone для инициализации различных представлений в зависимости от авторизации пользователя. В приведенном ниже примере я определяю базовый GridView, который содержит все стандартные и общие варианты поведения. AdminGridView и EditorGridView содержат определенные функции авторизованного пользователя. В приведенном ниже упрощенном примере обработчик щелчков будет подключен только для администраторов.

Приятно то, что все инкапсулировано, так что только Factory должна знать о AdminGridView и EditorGridView. Ваш код будет просто взаимодействовать с GridView.

// GridView is an abstract class and should not be invoked directly 
var GridView = Backbone.View.extend({ 

    // put all common / default code here

    _template: _.template($('#grid').html()),

    initialize: function(){
        this.model.bind('change', this.render, this);
    }.

    onButtonClick: function(){
        // do something
    },

    render: function(){ 
        $(this.el).html(this._template(this.model));
    } 
}, { 

    create: function (options) { 
        switch (options.authorization.get('type')) { 
            case 'admin': 
                return new AdminGridView(options); 
            case 'editor': 
                return new EditorGridView(options); 
            default:
                throw new Error('Authorization type ' + options.authorization.get('type') + ' not supported.'); 
        } 
    } 
}); 

var AdminGridView = GridView.extend({
    // put admin specific code here
    events: {
        'click .button': 'onButtonClick'
    }
}); 

var EditorGridView = GridView.extend({
    // put editor specific code here
});

var authorization = new Backbone.Model({ type: 'admin' });
var gridView = GridView.create({ model: someModel, authorization: authorization });
$('body').append((gridView.render().el))
2 голосов
/ 16 ноября 2011

Все на стороне клиента может быть взломано.Итак, то, что мы делаем в нашем одностраничном приложении js - это права на сервере.Мы объединяем список прав для каждого пользователя и имеем токен OAuth, который мы передаем клиенту и отправляем обратно с каждым запросом.затем на стороне сервера перед тем, как предпринять какое-либо действие, мы видим, аутентифицирован ли пользователь для этого действия.

Конечно, это не защитит вас от кого-то в кафе с firesheep ... но это еще одна проблема.

1 голос
/ 15 ноября 2011

То, как мы справляемся с этим, позволяет серверу отправлять нам html, который должен быть отображен на основе решения или решений, которые приводят к последствиям.что-то вроде этого

this.ActionFor(Model)
                .Decision<Authentication1>()
                .Decision<Authentication2>()
                .Consequence<HTMLRenderer>()

Вероятно, вы можете использовать этот шаблон аналогичным образом в JS, если считаете, что вам нужно.

1 голос
/ 15 ноября 2011

Поскольку вы упомянули магистраль, ваш код не должен быть

куча обработчиков нажатий jQuery

но вместо этого вы можете использовать модели для хранения данных об авторизации и соответствующим образом реагировать на ваши представления.

0 голосов
/ 15 ноября 2011

На стороне клиента, пусть JQuery позаботится об этом. Если элемента там нет, он ничего не делает. Он только прикрепляет обработчики событий к тем элементам, которые он находит, вам не нужно проверять if-an-element-exist, просто используйте селекторы JQuery.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...