Модуль Dnn SPA с WebApi работает для администраторов, но не для зарегистрированных пользователей. - PullRequest
0 голосов
/ 08 ноября 2018

У меня есть работающий модуль Dnn SPA, основанный на Angular 6, который выполняет вызовы к Dnn Service Framework.Все это прекрасно работает для пользователей, принадлежащих к роли администраторов, но когда пользователь входит в систему только с ролями «Все пользователи» или «Зарегистрированные пользователи», мы получаем следующую ошибку в консоли Chrome Dev:

ОШИБКА TypeError:Невозможно прочитать свойство 'длина' неопределенного в http.js: 108 в Array.forEach () в HttpHeaders.lazyInit (http.js: 102) в HttpHeaders.push ../ node_modules/@angular/common/fesm5/http.js.HttpHeaders.init (http.js: 166) в HttpHeaders.push ../ node_modules/@angular/common/fesm5/http.js.HttpHeaders.forEach (http.js: 235) в Observable._subscribe (http.js:1435) в Observable.push ../ node_modules / rxjs / _esm5 / internal / Observable.js.Observable._trySubscribe (ReplaySubject.js: 83) в Observable.push ../ node_modules / rxjs / _esm5 / internal / Observable.js.Observable.subscribe (ReplaySubject.js: 69) в tryCatch.js: 17 в subscribeToResult (index.js: 1)

Я подумал, что, возможно, по какой-то причине HTTPHeaders не были добавлены нашимиперехватчик, но глядя на NНа вкладке «Работа», ни один из наших звонков не выполняется.

Попытки решить проблему:

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

export function appInitializer(configurationService: ConfigurationService) {
  configurationService.configuration.antiforgeryToken = dnnService.framework.getAntiForgeryValue();
  configurationService.apiPath = dnnService.framework.getServiceRoot(dnnService.path);
  configurationService.configuration.moduleId = dnnService.moduleId;
  configurationService.configuration.tabId = dnnService.tabId;
  configurationService.configuration.tabModuleId = dnnService.tabModuleId;
  console.log('configuration for app initializer: ', configurationService);

  return () => true;
}

Проверка токена защиты от подделки

Один HTTPHeader, который необходимо добавить, является токеном защиты от подделки

dnnService.framework.getAntiForgeryValue()

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

Добавлена ​​дополнительная регистрация для вызовов WebApi

Я нашел одну запись в журнале, которая была подозрительной, но не смогла связать это с проблемой:

[WARN] DotNetNuke.Entities.Tabs.TabController - неверный tabId -1 портала 0

Изменен уровень доступа для всех контроллеров WebApi
Я изменил все DnnModuleAuthorisationна следующее:

[DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.Anonymous)]

Я также пытался

[DnnModuleAuthorize(AccessLevel = SecurityAccessLevel.View)]

Ничего не изменилось.

Проверьте, срабатывает ли первый вызов конечной точки HTTP WebApi
В ngDoBootstrap я делаю первый HTTP-вызов, когда все перестает функционировать, поэтому я могу поверить, что на самом деле есть проблема в Angular:

 ngDoBootstrap(app) {
    console.log('about to get settings');

    this.settingsService.getSettings().subscribe((settings: Settings) => {
      console.log('fired call to get settings');  //<- Never gets here    
    });
  }

console.logв getSettings (). подписка никогда не срабатывает!

Любой намек или руководство о том, что еще нужно проверить, было бы замечательно.

Ответы [ 3 ]

0 голосов
/ 16 ноября 2018

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

РЕДАКТИРОВАТЬ: я смог протянуть руку и получить код, который я написал для этого. Вот как я получил API в чистом модуле SPA (только для HTML / JS):

[JavaScript:{ jsname: "AngularJs" }] 
[JavaScript:{ path: "~/DesktopModules/module/dist/app.build.js"}] 

<div id="root" 
    data-module-id="[ModuleContext:ModuleId]" 
    data-is-superuser="[ModuleContext:IsSuperUser]" 
    data-anti-forgery-token="[AntiForgeryToken:true]" 
    ng-cloak="true" 
    ng-switch="{{'[ModuleContext:IsSuperUser]'.toLowerCase()}}">
    <!-- non-admins -->
    <div ng-switch-when="false">
        <app></app>
    </div>
    <!-- admins -->
    <div ng-switch-when="true">
        <div class="panel panel-info">
            <div class="panel-heading">
                <h3 class="panel-title" ng-bind="::'App'"></h3>
            </div>
        </div>
    </div>
</div>

<script>
    angular.element(function () {
        angular.bootstrap(document.getElementById('root'), ['App']);
    });
</script>
0 голосов
/ 22 ноября 2018

Оказывается, это RequestVerificationToken. По какой-то причине Dnn выводит токен только для администраторов, или когда в скине присутствует окно поиска (?), Которое я удалил.

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

<div id="search-top" style="display:none !important">
    <dnn:SEARCH ID="dnnSearch2" runat="server" ShowSite="false" ShowWeb="false" EnableTheming="true" Submit="Search" CssClass="SearchButton" />
</div>

Я протестировал это с пользователями без прав администратора, и это работает.

Для получения дополнительной информации см. Связанную ошибку Dnn 9, размещенную на DnnTracker :

0 голосов
/ 08 ноября 2018

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

using DotNetNuke.Framework;
using DotNetNuke.Common;

//7.2 and lower
if (Globals.DataBaseVersion.Major < 7 || (Globals.DataBaseVersion.Major == 7 && Globals.DataBaseVersion.Minor < 2))
{
    jQuery.RequestDnnPluginsRegistration();
}
else
{
    //7.3 and higher
    JavaScriptLibraries.JavaScript.RequestRegistration(JavaScriptLibraries.CommonJs.DnnPlugins);
}
...