Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to properly import and use the MSAL (Microsoft Authentication Library for js) into a typescript react single page application?

Tags:

Problem

I can't seem to get the MSAL library to import properly into my typescript code. I'm using the MSAL for JS library (which is supposed to have typings) in a simple typescript/react project scaffolded using the create-react-app with react-typescript scripts. I'm new to typescript and not sure if I'm missing something obvious or if there is a problem with the MSAL package when using it with typescript projects.

Details:

  1. I added the MSAL package from NPM using npm install --save msal.
  2. I attempted to import the MSAL into my .ts using different forms of import {Msal} from 'msal';
  3. This results in a typescript error Could not find a declaration file for module 'msal'. '<path>/node_modules/msal/out/msal.js' implicitly has an 'any' type.
  4. Thinking that was odd, I looked at the the node_module/msal/out folder and saw a 'msal.d.ts' file, which is what I would expect.
  5. When I look at the contents of the msal.d.ts file, I don't see any exports, which I would normally expect to see.
  6. I tried install the declaration from @types using npm install --save-dev @types/msal, but it doesn't exist.
  7. I also tried importing it into my file using let Msal = require('Msal');, but get an error that the Msal.UserAgentApplication isn't a constructor.
  8. I didn't have much luck trying to use the /// reference directive and adding a script tag to the main index.html. This also doesn't feel like the right way to solve the problem.

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"   ] } 
like image 437
nbrowne Avatar asked May 28 '17 14:05

nbrowne


People also ask

What is Microsoft authentication library Msal?

The Microsoft Authentication Library (MSAL) enables developers to acquire tokens from the Microsoft identity platform in order to authenticate users and access secured web APIs. It can be used to provide secure access to Microsoft Graph, other Microsoft APIs, third-party web APIs, or your own web API.

How do I get the Msal access token in react?

Acquiring an access token When using @azure/msal-react and @azure/msal-browser you will call acquireTokenSilent on the PublicClientApplication instance. If you need to obtain an access token inside a component or hook that lives under MsalProvider you can use the useMsal hook to get the objects you need.

What is Msal JS?

The MSAL library for JavaScript enables client-side JavaScript web applications, running in a web browser, to authenticate users using Azure AD work and school accounts (AAD), Microsoft personal accounts (MSA) and social identity providers like Facebook, Google, LinkedIn, Microsoft accounts, etc.


2 Answers

It looks like the latest version of MSAL.js does have a CommonJS export. You can now just do the following in TypeScript (tested with version 2.3.3 of TypeScript and 0.1.3 of MSAL.js):

import * as Msal from 'msal'; 

Now in your .ts (or in my case .tsx file) you can, for instance, setup a click event handler and create a UserAgentApplication object:

// 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>     ); } 
like image 97
Henry Daehnke Avatar answered Oct 15 '22 23:10

Henry Daehnke


As you have correctly mentioned - in the msal.d.ts there are no exports - its not a module, and therefore you should not try importing.

Instead you can use it like this:

/// <reference path="./node_modules/msal/out/msal.d.ts" />  const userAgentApplication = new Msal.UserAgentApplication("your_client_id", null, (errorDes, token, error, tokenType) =>     {      }); 

Note that even in readme they specify only one way of using their library - by including script tag, not by importing module. And further looking into their source code shows they are not using modules as well.

like image 20
Amid Avatar answered Oct 15 '22 21:10

Amid