Как правильно импортировать и использовать MSAL (библиотеку аутентификации Microsoft для js) в одностраничное приложение для реагирования на машинописный текст?

Проблема

Кажется, я не могу заставить библиотеку MSAL правильно импортировать в мой машинописный код. Я использую библиотеку MSAL для JS (которая должна иметь typings) в простом проекте typescript / react, созданном с помощью приложения create-react-app со сценариями react-typescript. Я новичок в машинописном тексте и не уверен, что мне не хватает чего-то очевидного или есть проблема с пакетом MSAL при его использовании с проектами машинописного текста.

Подробности:

  1. Я добавил пакет MSAL из NPM, используя npm install --save msal.
  2. Я попытался импортировать MSAL в свой .ts, используя разные формы import {Msal} from 'msal';
  3. Это приводит к ошибке машинописного текста Could not find a declaration file for module 'msal'. '<path>/node_modules/msal/out/msal.js' implicitly has an 'any' type.
  4. Подумав, что это было странно, я посмотрел на папку node_module / msal / out и увидел файл msal.d.ts, чего я и ожидал.
  5. Когда я смотрю на содержимое msal.d.ts, я не вижу экспорта, которого я обычно ожидал бы увидеть.
  6. Я попытался установить объявление из @types с помощью npm install --save-dev @types/msal, но его не существует.
  7. Я также попытался импортировать его в свой файл с помощью let Msal = require('Msal');, но получил сообщение об ошибке, что Msal.UserAgentApplication не является конструктором.
  8. Мне не повезло с попыткой использовать директиву /// reference и добавить тег скрипта в основной index.html. Это также не похоже на правильный способ решения проблемы.

ExampleMsal.ts

import { observable, action, computed } from 'mobx';
import * as Msal from 'msal'; // <-- This line gives the error

class ExampleMsal{
    @observable 
    private _isLoggedIn: boolean;

    constructor() {
        this._isLoggedIn = false;
    }

    @computed 
    get isLoggedIn(): boolean {
        return this._isLoggedIn;
    }

    @action 
    signIn() {

        let userAgentApplication = new Msal.UserAgentApplication('<client-id>', null, 
        function (errorDes: string, token: string, error: string, tokenType: string) {
            // this callback is called after loginRedirect OR acquireTokenRedirect 
            // (not used for loginPopup/aquireTokenPopup)
        }
        );

        userAgentApplication.loginPopup(['user.read']).then(function(token: string) {
            let user = userAgentApplication.getUser();
            if (user) {
                // signin successful
                alert('success');
            } else {
                // signin failure
                alert('fail');
            }
        }, function (error: string) {
            // handle error
            alert('Error' + error);
        });        
        this._isLoggedIn = true;
    }

    @action 
    signOut() {
        this._isLoggedIn = false;
    }
}

export default ExampleMsal;

tsconfig.json

{
  "compilerOptions": {
    "outDir": "build/dist",
    "module": "commonjs",
    "target": "es5",
    "lib": ["es6", "dom"],
    "sourceMap": true,
    "allowJs": true,
    "jsx": "react",
    "moduleResolution": "node",
    "rootDir": "src",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "strictNullChecks": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "experimentalDecorators": true
  },
  "exclude": [
    "node_modules",
    "build",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts"
  ],
  "types": [
    "typePatches"
  ]
}

person nbrowne    schedule 28.05.2017    source источник


Ответы (4)


Как вы правильно заметили - в msal.d.ts нет экспорта - это не модуль, и поэтому вам не следует пытаться импортировать.

Вместо этого вы можете использовать это так:

/// <reference path="./node_modules/msal/out/msal.d.ts" />

const userAgentApplication = new Msal.UserAgentApplication("your_client_id", null, (errorDes, token, error, tokenType) =>
    {

    });

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

person Amid    schedule 29.05.2017
comment
Определение ссылочного пути в сочетании с включением js-файла из CDN в мой index.html заставило меня работать. Я обновлюсь, если найду более чистый способ сделать это. - person nbrowne; 31.05.2017
comment
Привет, Найджел, вы можете загрузить свой проект на свой Github? Я пытаюсь найти образцы с помощью React и MSAL. заранее спасибо - person Thiago Custodio; 19.06.2017
comment
Более поздние версии MSAL, похоже, сейчас работают хорошо, я использую версию 0.1.3, и она проста: import * as Msal from 'msal'; работает хорошо. - person StephenD; 24.12.2017

Похоже, что последняя версия MSAL.js имеет экспорт CommonJS. Теперь вы можете просто сделать следующее в TypeScript (протестировано с версией 2.3.3 TypeScript и 0.1.3 MSAL.js):

import * as Msal from 'msal';

Теперь в вашем .ts (или в моем случае .tsx файле) вы можете, например, настроить обработчик событий щелчка и создать объект UserAgentApplication:

// In you class somewhere
private userAgentApplication: any = undefined;

// The login button click handler
handleLoginClick = (event: any): void => {
    if (!this.userAgentApplication) {
        this.userAgentApplication = new Msal.UserAgentApplication(
            'clientID string', 'authority string or empty', this.authCallback, { cacheLocation: 'localStorage'});
    }
    // Other login stuff...
}

// In React render()
public render() {
    return (
        <Button
            bsStyle="warning"
            type="button"
            onClick={(e) => this.handleLoginClick(e)}
        >
        Log in
        </Button>
    );
}
person Henry Daehnke    schedule 07.11.2017
comment
Я смог сделать то, что вы предложили для создания нового UserAgentAppliation, однако в предыдущем коде (где я загружал Msal из CDN) я сделал следующее Msal.Storage("localStorage").getItem(...). Теперь это дает ошибку, когда я использую import * as Msal from 'msal'. Есть ли способ заставить это работать? - person RHarris; 08.11.2017

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

npm install msalx

Вы можете найти исходный код и пример использования в React по адресу: https://github.com/malekpour/microsoft-authentication-library-for-js#example

person Ali Malekpour    schedule 29.07.2017
comment
Вы сэр герой - person Dibran; 03.08.2017

Если вы установите export-loader (npm install exports-loader --save-dev), вы можете избежать тега script и добавить в свои директивы следующее:

var Msal = require("exports-loader?Msal!../../../node_modules/msal/out/msal.js"); 
person Kyle Reed    schedule 17.06.2017
comment
Я получаю исключение: неожиданный "!" в 'export-loader? Msal! ./ node_modules / msal / out / msal.js'. Не используйте синтаксис импорта для настройки загрузчиков веб-пакетов import / no-webpack-loader-syntax - person Paweł Skorupiński; 02.08.2017
comment
Мне удалось выполнить импорт, используя это, но я получаю следующую ошибку: Msal.UserAgentApplication is not a constructor - person Jed; 29.08.2017