Как использовать Расширение JS для основанного на роли приложения

Как другие упомянули, Списки и кортежи являются оба контейнерами, которые могут использоваться, чтобы хранить объекты Python. Списки расширяемы, и их содержание может измениться присвоением, с другой стороны, кортежи неизменны.

кроме того, списки не могут использоваться в качестве ключей в словаре, тогда как кортежи могут.

14
задан Abdel Raoof 21 November 2009 в 14:59
поделиться

4 ответа

Мне пришлось решить аналогичную проблему в приложении, которое я в настоящее время разрабатываю, но разрешения зависят от страны пользователя.

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

Я обнаружил, что есть несколько способов сделать это, но, в частности, есть два подхода. которые самые разумные. Независимо от подхода, необходимо учитывать две вещи: 1) какой JavaScript использовать для сервера и как избежать обслуживания ненужной логики, и 2) как избежать выполнения логики, недоступной пользователю.

Ленивая загрузка и конфигурация разрешений:

  1. Все виджеты в моем приложении лениво загружаются через dojo.require , поэтому не нужно было беспокоиться о ненужном включении JavaScript, который неприменим к Пользователь. Я не очень хорошо знаком с библиотекой ExtJs, но, насколько я видел, она не предоставляет сопоставимого метода; однако необходим синхронный вызов ajax, за которым следует eval. В любом случае, в этом методе важно, чтобы функциональность компонентов не пересекалась с разными файлами (к тому же это вообще хороший дизайн). Каждый файл должен быть собственным классом, который управляет определенным виджетом или другим элементом пользовательского интерфейса.

  2. Затем я устанавливаю разрешения в сгенерированном сервером классе конфигурации JavaScript. Затем на этот класс можно ссылаться во всем приложении, чтобы узнать, что разрешено, а что нет.

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

com.project.frontController.prototype.init = function(widgets) {
   var permissions = com.project.config.permissions;

   // For each widget in the controller
   for ( var i=0, l=widgets.length; i<l; ++i ) {
       // If access is restricted to the widget (by id), then disable it.
       if ( !permissions[ widgets[i].id ] {
           com.project.util.disable(widgets[i].btnAccessNode);
       }
       // Otherwise, leave it enabled and connect the necessary event handlers.
       else {
           // connect an onclick handler or whatever is required for the widget
       }
   }
};

И конфигурация выглядела примерно так:

com.project.config.permissions = {
    "widgetAbc": {
        btnAccessNode:     "#some-css-selector",
        otherWidgetConfig: "etc"
    },
    "widgetXyz": {
        btnAccessNode:     "div.some-css-selector"
    }
};

Компиляция и проверка функциональности:

  1. Некоторые приложения будут компилировать все из его JavaScript в один файл, а затем передать его клиенту. Если ваше приложение делает такую ​​вещь, и вы можете делать это динамически, весь необходимый JS может быть определен на стороне сервера до его обслуживания. Конечно, это повлечет за собой некоторые накладные расходы; однако вы можете кэшировать скомпилированные версии по ролям. Если ролей мало, то этот кеш можно легко подготовить, просто включив один конкретный сценарий.

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

Например, включение вашего скрипта может выглядеть так:

<script type="text/javascript" src="/js/compiler.php?role=moderator"></script>

И ваша проверка функциональности будет чем-то например:

com.project.frontController.prototype.init = function(widgets) {
   // For each widget in the controller
   for ( var i=0, l=widgets.length; i<l; ++i ) {
       // If the widget controller doesn't exist, disable it.
       if ( !com.project.util.widgetExists[ widgets[i].id ] {
           com.project.util.disable(widgets[i].btnAccessNode);
       }
       // Otherwise, leave it enabled and connect the necessary event handlers.
       else {
           // connect an onclick handler or whatever is required for the widget
       }
   }
};

или

com.project.someWidget.prototype.launchOtherWidget = function() {
    if ( typeof otherWidget != "undefined" ) {
        (new otherWidget()).open();
    }
};

Обратите внимание, что оба метода очень похожи по реализации. Я бы сказал, что лучший способ определить между ними - рассмотреть размер вашей кодовой базы, доступные вам инструменты для компиляции на лету и кэширование этих скомпилированных пакетов на основе ролей. Для моего проекта в среде не только отсутствовал компилятор, но и была большая база кода (увеличено 1,3 МБ / 296 КБ по умолчанию плюс библиотека dojo), что было неприемлемо, поскольку клиент был больше заинтересован в поддержании низкой нагрузки приложения. раз.

включение вашего скрипта может выглядеть так:

<script type="text/javascript" src="/js/compiler.php?role=moderator"></script>

И ваша проверка функциональности будет примерно такой:

com.project.frontController.prototype.init = function(widgets) {
   // For each widget in the controller
   for ( var i=0, l=widgets.length; i<l; ++i ) {
       // If the widget controller doesn't exist, disable it.
       if ( !com.project.util.widgetExists[ widgets[i].id ] {
           com.project.util.disable(widgets[i].btnAccessNode);
       }
       // Otherwise, leave it enabled and connect the necessary event handlers.
       else {
           // connect an onclick handler or whatever is required for the widget
       }
   }
};

или

com.project.someWidget.prototype.launchOtherWidget = function() {
    if ( typeof otherWidget != "undefined" ) {
        (new otherWidget()).open();
    }
};

Обратите внимание, что оба метода очень похожи по реализации. Я бы сказал, что лучший способ сделать выбор между ними - рассмотреть размер вашей кодовой базы, инструменты, доступные вам для компиляции на лету, и кэширование этих скомпилированных пакетов на основе ролей. Для моего проекта не только компилятор не был доступен в среде, но и база кода была большой (1,3 МБ раздут / 296 КБ по умолчанию плюс библиотека dojo), что было неприемлемо, поскольку клиент был больше заинтересован в поддержании низкой нагрузки приложения. раз.

включение сценария может выглядеть так:

<script type="text/javascript" src="/js/compiler.php?role=moderator"></script>

И ваша проверка функциональности будет примерно такой:

com.project.frontController.prototype.init = function(widgets) {
   // For each widget in the controller
   for ( var i=0, l=widgets.length; i<l; ++i ) {
       // If the widget controller doesn't exist, disable it.
       if ( !com.project.util.widgetExists[ widgets[i].id ] {
           com.project.util.disable(widgets[i].btnAccessNode);
       }
       // Otherwise, leave it enabled and connect the necessary event handlers.
       else {
           // connect an onclick handler or whatever is required for the widget
       }
   }
};

или

com.project.someWidget.prototype.launchOtherWidget = function() {
    if ( typeof otherWidget != "undefined" ) {
        (new otherWidget()).open();
    }
};

Обратите внимание, что оба метода очень похожи по реализации. Я бы сказал, что лучший способ сделать выбор между ними - рассмотреть размер вашей кодовой базы, инструменты, доступные вам для компиляции на лету, и кэширование этих скомпилированных пакетов на основе ролей. Для моего проекта не только компилятор был недоступен в среде, но и база кода была большой (1,3 МБ раздут / 296 КБ по умолчанию плюс библиотека dojo), что было неприемлемо, поскольку клиент был больше заинтересован в поддержании низкой нагрузки приложения. раз.

Я бы сказал, что лучший способ определить между ними - рассмотреть размер вашей кодовой базы, доступные вам инструменты для компиляции на лету и кэширование этих скомпилированных пакетов на основе ролей. Для моего проекта не только компилятор не был доступен в среде, но и база кода была большой (1,3 МБ раздут / 296 КБ по умолчанию плюс библиотека dojo), что было неприемлемо, поскольку клиент был больше заинтересован в поддержании низкой нагрузки приложения. раз.

Я бы сказал, что лучший способ определить между ними - рассмотреть размер вашей кодовой базы, доступные вам инструменты для компиляции на лету и кэширование этих скомпилированных пакетов на основе ролей. Для моего проекта не только компилятор был недоступен в среде, но и база кода была большой (1,3 МБ раздут / 296 КБ по умолчанию плюс библиотека dojo), что было неприемлемо, поскольку клиент был больше заинтересован в поддержании низкой нагрузки приложения. раз.

14
ответ дан 1 December 2019 в 13:33
поделиться

Всегда обеспечивать безопасность на стороне сервера, скрывая элементы управления во внешнем интерфейсе, этого недостаточно.
РЕДАКТИРОВАТЬ
На стороне клиента? ну, вы можете следовать любому совету в других ответах, но правда в том, что пользователь может выполнять произвольный javascript, изменять DOM страницы и выполнять любой запрос, который он хочет.

0
ответ дан 1 December 2019 в 13:33
поделиться

Не передавать клиенту функциональные возможности, недоступные пользователю. Вы можете загружать файлы js динамически, но сервер приложений должен обеспечивать соблюдение ваших правил; без роли, без JS.

  var jsFile = document.createElement('script');
  jsFile.setAttribute( "type", "text/javascript" );
  jsFile.setAttribute( "src", 'someFileName.js' );
  document.getElementsByTagName("head")[0].appendChild(jsFile);

Вы можете использовать LDAP или более простое серверное решение, но (опять же) не показывайте JS пользователям, у которых нет на это прав. На клиенте проверьте наличие класса (во время разработки создайте один класс для каждого файла JS) и не пытайтесь создать объект, когда его класс не загружен.

0
ответ дан 1 December 2019 в 13:33
поделиться

Это зависит от того, насколько универсальны ваши докладчики. Если ваши докладчики являются полностью UI agnostic (можно повторно использовать между WinForms и WebForms), то вам придется абстрагироваться от операции перенаправления. В WebForms операция перенаправления будет реализована в представлении Response.Redirect. В WinForms (я отказываюсь от большого опыта работы с WinForms) я предполагаю, что он будет реализован SomeForm.Show.

Одним из простых вариантов «вне головы» было бы включение в интерфейс представления метода SunViewX (). Для каждой формы, на которую можно логически перенаправить представление, можно использовать одну форму. Альтернативно, представление может реализовать метод интерфейса, такой как Show (ConnectedViews), где ConnectedViews является перечислением, которое включает в себя значение для каждого из представлений, которое может быть «перенаправлено» в из конкретного представления. Это перечисление будет жить на уровне докладчика.

Вышеуказанные подходы специфичны для пар вид-презентатор. Вместо этого вы можете реализовать его как общесистемную вещь. Логика будет аналогична описанной выше, реализованной в базовом представлении и презентаторе. Для каждой формы может существовать __ () SunView или метод Show (Views), где Views является перечислением всех форм.

Это бросание между инкапсуляцией и DRY-ness.

-121--4716566-

Еще одно решение:

  • нет панели инструментов, кроме сегментированного элемента управления (eyecandy)

     UIAcitySheet * actionSheet = [[UIAcitySheet alloc] initWeyTitle: nil
    делегат: ноль
    cancelButityTitle: ноль
    destructiveButtonTitle:nil
    otherButityTitle: ноль];
    
    [actionSheet setActionSheetStyle: UIAcateSheetStyleBlackTranslucent];
    
    CGRect picterFrame = CGRectMake (0, 40, 0, 0);
    
    UIPicureView * picterView = [[UIPicureView alloc] initWeyFrame: picterFrame];
    picterView.showsSeliceIndicator = YES;
    picterView.dateSource = self;
    picterView.delegate = self;
    
    [actionSheet addSubview: выбор вида];
    [выбор Деблокирование вида];
    
    UISegingControl * closeButton = [[UISegingControl alloc] initWityItems: [NSAray arrayWityObject: @ «Close»]];
    closeButton.momentary = YES;
    closeButton.frame = CGRectMake (260, 7.0f, 50.0f, 30.0f);
    closeButton.segsControlStyle = UISegsControlStyleBar;
    closeButton.tintColor = [UIColor blackColor];
    [closeButton addTarget: self action: @ selector (dismissActionSheet:) forControlEvents: UIControlEventStartChanged];
    [actionSheet addSubview: closeButton];
    [closeButton release];
    
    [actionSheet sunInView: [[UIApplication sharedApplication] keyWindow]];
    
    [actionSheet setBounds: CGRectMake (0, 0, 320, 485)];
    
-121--2038226-

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

Это правда, что он может быть взломан, так что первоначальный объект делает вид, что имеет больше прав, чем он на самом деле; однако хакер получит нарушение безопасности на сервере при попытке сделать то, что ему не разрешено. Таким образом, логика клиентской стороны, которая применяет безопасность, только для выгоды пользователя,так что он не видит больше, чем может. Проверка на стороне сервера (когда запрашивается действие) - это то, что фактически обеспечивает безопасность.

4
ответ дан 1 December 2019 в 13:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: