web-dev-qa-db-fra.com

Comment importer et utiliser correctement la MSAL (bibliothèque d'authentification Microsoft pour js) dans une application de page unique de typeScript?

Problème

Je n'arrive pas à obtenir la bibliothèque MSAL à importer correctement dans mon code TypeScript. J'utilise la bibliothèque MSAL pour JS (qui est censée avoir des typages) dans un projet TypeScript/react simple échafaudé en utilisant l'application create-react-app avec des scripts react-TypeScript. Je suis nouveau sur TypeScript et je ne sais pas si je manque quelque chose d'évident ou s'il y a un problème avec le package MSAL lors de son utilisation avec des projets TypeScript.

Détails:

  1. J'ai ajouté le package MSAL de NPM en utilisant npm install --save msal.
  2. J'ai tenté d'importer le MSAL dans mes .ts en utilisant différentes formes de import {Msal} from 'msal';
  3. Il en résulte une erreur TypeScript Could not find a declaration file for module 'msal'. '<path>/node_modules/msal/out/msal.js' implicitly has an 'any' type.
  4. Pensant que c'était étrange, j'ai regardé le dossier node_module/msal/out et j'ai vu un fichier 'msal.d.ts', ce à quoi je m'attendais.
  5. Quand je regarde le contenu du fichier msal.d.ts , je ne vois aucune exportation, que je m'attendrais normalement à voir.
  6. J'ai essayé d'installer la déclaration de @types en utilisant npm install --save-dev @types/msal, Mais elle n'existe pas.
  7. J'ai également essayé de l'importer dans mon fichier à l'aide de let Msal = require('Msal');, mais j'obtiens une erreur indiquant que Msal.UserAgentApplication n'est pas un constructeur.
  8. Je n'ai pas eu beaucoup de chance en essayant d'utiliser la directive de référence /// et en ajoutant une balise de script au index.html principal. Cela ne semble pas non plus être la bonne façon de résoudre le problème.

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"
  ]
}
17
nbrowne

Comme vous l'avez correctement mentionné - dans le msal.d.ts il n'y a pas d'export - ce n'est pas un module, et donc vous ne devriez pas essayer d'importer.

Au lieu de cela, vous pouvez l'utiliser comme ceci:

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

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

    });

Notez que même dans le fichier Lisezmoi, ils ne spécifient qu'une seule façon d'utiliser leur bibliothèque - en incluant une balise de script, pas en important un module. Et un examen plus approfondi de leur code source montre qu'ils n'utilisent pas également les modules.

10
Amid

Il ressemble à la dernière version de MSAL.js does a une exportation CommonJS. Vous pouvez maintenant simplement faire ce qui suit dans TypeScript (testé avec la version 2.3.3 de TypeScript et 0.1.3 de MSAL.js):

import * as Msal from 'msal';

Maintenant dans votre .ts (ou dans mon cas .tsx fichier), vous pouvez, par exemple, configurer un gestionnaire d'événements Click et créer un objet 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>
    );
}
11
Henry Daehnke

J'ai eu le même problème et je ne pouvais pas attendre que l'auteur le corrige, j'ai donc bifurqué et modifié le code d'origine. Tout comme un correctif temporaire, vous pouvez utiliser ma version msalx au lieu de msal.

npm install msalx

Vous pouvez trouver le code source et un exemple d'utilisation dans react sur: https://github.com/malekpour/Microsoft-authentication-library-for-js#example

10
Ali Malekpour

Si vous installez le chargeur d'exportation (npm install exports-loader --save-dev) vous pouvez éviter la balise de script et ajouter ce qui suit à vos directives:

var Msal = require("exports-loader?Msal!../../../node_modules/msal/out/msal.js"); 
6
Kyle Reed

Comme indiqué dans wiki la bonne façon d'importer est:

import * as Msal from 'msal';
1
vzhikness