如何正确地将 MSAL(用于 js 的 Microsoft 身份验证库)导入并使用到打字稿反应单页应用程序中?
How to properly import and use the MSAL (Microsoft Authentication Library for js) into a typescript react single page application?
问题
我似乎无法将 MSAL 库正确导入到我的打字稿代码中。我在一个简单的 typescript/react 项目中使用 MSAL for JS 库(应该有类型),该项目使用带有 react-typescript 脚本的 create-react-app 脚手架。我是打字稿的新手,不确定我是否遗漏了一些明显的东西,或者在将它用于打字稿项目时 MSAL 包是否有问题。
详情:
- 我使用
npm install --save msal
从 NPM 添加了 MSAL 包。
- 我尝试使用不同形式的
import {Msal} from 'msal';
将 MSAL 导入我的 .ts
- 这会导致打字稿错误
Could not find a declaration file for module 'msal'. '<path>/node_modules/msal/out/msal.js' implicitly has an 'any' type.
- 觉得很奇怪,我查看了 node_module/msal/out 文件夹并看到了一个 'msal.d.ts' 文件,这是我所期望的。
- 当我查看 msal.d.ts 文件的内容时,我没有看到任何我通常希望看到的导出。
- 我尝试使用
npm install --save-dev @types/msal
从 @types 安装声明,但它不存在。
- 我也尝试使用
let Msal = require('Msal');
将其导入到我的文件中,但出现 Msal.UserAgentApplication 不是构造函数的错误。
- 我在尝试使用 /// 引用指令并将脚本标记添加到主 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"
]
}
正如您正确提到的那样 - 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) =>
{
});
请注意,即使在自述文件中,他们也只指定了一种使用其库的方式 - 通过包含脚本标签,而不是通过导入模块。进一步查看他们的源代码表明他们也没有使用模块。
如果你安装了 exports-loader (npm install exports-loader --save-dev
),你可以避免使用脚本标签并将以下内容添加到你的指令中:
var Msal = require("exports-loader?Msal!../../../node_modules/msal/out/msal.js");
我也遇到了同样的问题,等不及作者修复,于是fork修改了原代码。作为临时修复,您可以使用我的版本 msalx
而不是 msal
.
npm install msalx
您可以在 React 中找到源代码和示例用法:https://github.com/malekpour/microsoft-authentication-library-for-js#example
看起来 MSAL.js 的最新版本 有 CommonJS 导出。您现在可以在 TypeScript 中执行以下操作(使用 TypeScript 2.3.3 版和 MSAL.js 的 0.1.3 版进行测试):
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>
);
}
问题
我似乎无法将 MSAL 库正确导入到我的打字稿代码中。我在一个简单的 typescript/react 项目中使用 MSAL for JS 库(应该有类型),该项目使用带有 react-typescript 脚本的 create-react-app 脚手架。我是打字稿的新手,不确定我是否遗漏了一些明显的东西,或者在将它用于打字稿项目时 MSAL 包是否有问题。
详情:
- 我使用
npm install --save msal
从 NPM 添加了 MSAL 包。 - 我尝试使用不同形式的
import {Msal} from 'msal';
将 MSAL 导入我的 .ts
- 这会导致打字稿错误
Could not find a declaration file for module 'msal'. '<path>/node_modules/msal/out/msal.js' implicitly has an 'any' type.
- 觉得很奇怪,我查看了 node_module/msal/out 文件夹并看到了一个 'msal.d.ts' 文件,这是我所期望的。
- 当我查看 msal.d.ts 文件的内容时,我没有看到任何我通常希望看到的导出。
- 我尝试使用
npm install --save-dev @types/msal
从 @types 安装声明,但它不存在。 - 我也尝试使用
let Msal = require('Msal');
将其导入到我的文件中,但出现 Msal.UserAgentApplication 不是构造函数的错误。 - 我在尝试使用 /// 引用指令并将脚本标记添加到主 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"
]
}
正如您正确提到的那样 - 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) =>
{
});
请注意,即使在自述文件中,他们也只指定了一种使用其库的方式 - 通过包含脚本标签,而不是通过导入模块。进一步查看他们的源代码表明他们也没有使用模块。
如果你安装了 exports-loader (npm install exports-loader --save-dev
),你可以避免使用脚本标签并将以下内容添加到你的指令中:
var Msal = require("exports-loader?Msal!../../../node_modules/msal/out/msal.js");
我也遇到了同样的问题,等不及作者修复,于是fork修改了原代码。作为临时修复,您可以使用我的版本 msalx
而不是 msal
.
npm install msalx
您可以在 React 中找到源代码和示例用法:https://github.com/malekpour/microsoft-authentication-library-for-js#example
看起来 MSAL.js 的最新版本 有 CommonJS 导出。您现在可以在 TypeScript 中执行以下操作(使用 TypeScript 2.3.3 版和 MSAL.js 的 0.1.3 版进行测试):
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>
);
}