我正在创建一个 React Web 应用程序来向我的客户显示 Power Bi 报告。
流程如下:
我正在使用主用户方法遵循“为客户嵌入场景”。
如果我理解得好的话,认证流程是这样的: _ 当用户使用 firebase 进行身份验证时,他会转到仪表板页面 _ 要呈现 power bi 仪表板,我首先需要针对 Azure AD 进行身份验证(使用 clientSecret、clientID 和 TenantID)并接收用户的访问令牌。
这是我的仪表板.jsx 代码,我尝试在其中嵌入 Power BI 报告:
import React from 'react'
import { PowerBIEmbed } from 'powerbi-client-react';
import { models } from 'powerbi-client';
import axios from 'axios';
import { useEffect, useState } from 'react';
const obtainAccessToken = async () => {
try {
const tokenUrl = `https://login.microsoftonline.com/${import.meta.env.VITE_AZURE_TENANT_ID}/oauth2/token`;
const headers = {
"Content-Type": "application/x-www-form-urlencoded",
};
const body = new URLSearchParams();
body.append('client_id', import.meta.env.VITE_AZURE_CLIENT_ID);
body.append('client_secret', import.meta.env.VITE_AZURE_CLIENT_SECRET);
body.append('grant_type', 'client_credentials');
body.append('resource', 'https://analysis.windows.net/powerbi/api');
const response = await axios.post(tokenUrl, body, { headers });
console.log('access token = ' + response.data.access_token);
return response.data.access_token;
} catch (error) {
console.error(error);
}
};
function Dashboard() {
const [accessToken, setAccessToken] = useState(null);
useEffect(() => {
obtainAccessToken().then((token) => {
setAccessToken(token);
});
}, []);
return (
<PowerBIEmbed
embedConfig = {{
type: 'report', // Supported types: report, dashboard, tile, visual and qna
id: 'eff45871-db5c-4bd6-a953-c492f6045044',
embedUrl: 'https://app.powerbi.com/reportEmbed?reportId=eff45871-db5c-4bd6-a953-c492f6045044&groupId=b1554fa1-bd00-4640-850f-efc22a60b64c&w=2&config=eyJjbHVzdGVyVXJsIjoiaHR0cHM6Ly9XQUJJLUZSQU5DRS1DRU5UUkFMLUEtUFJJTUFSWS1yZWRpcmVjdC5hbmFseXNpcy53aW5kb3dzLm5ldCIsImVtYmVkRmVhdHVyZXMiOnsibW9kZXJuRW1iZWQiOnRydWUsInVzYWdlTWV0cmljc1ZOZXh0Ijp0cnVlfX0%3d',
accessToken: accessToken,
tokenType: models.TokenType.Aad,
settings: {
panes: {
filters: {
expanded: false,
visible: false
}
},
background: models.BackgroundType.Transparent,
}
}}
eventHandlers = {
new Map([
['loaded', function () {console.log('Report loaded');}],
['rendered', function () {console.log('Report rendered');}],
['error', function (event) {console.log(event.detail);}]
])
}
cssClassName = { "Embed-container" }
getEmbeddedComponent = { (embeddedReport) => {
window.report = embeddedReport;
}}
/>
)
}
export default Dashboard
我使用此代码得到的结果是,永远加载 Power BI 徽标,并且 chrome 开发工具控制台中出现以下错误:
我似乎无法从 Azure AD 获取访问令牌。也许还有另一个我看不到的问题。有人知道如何解决这个问题吗?预先感谢!
使用 React 开发人员示例,我们可以嵌入进行组织。但就您而言,为客户嵌入,在 MSAL-React 中,ClientCredential Auth 流程是为机密客户端应用程序设计的。 msal-react 是一个身份验证库,仅支持 SPA 类型的应用程序(公共客户端应用程序),因此库中不支持 ClientCredential 流。
因此,解决方法是从 Azure Function 获取嵌入令牌。
如果您在创建函数和代码以在 Azure 门户中获取令牌时遇到任何问题,请随时与我们联系。
您可以参考React Demo GitHub Repository。
我也遇到过同样的问题。
也许为时已晚,但我将展示如何使用 @azure/react 和 @azure/msal-browser 库来解决它。
首先,您需要为您的组织注册 Power BI。您可以在这里找到更多信息:https://learn.microsoft.com/en-us/power-bi/developer/embedded/register-app?tabs=customers
之后,如果您从 Azure 门户获得了 Power Bi 应用程序的 client_id,则需要创建 msal 实例的新实例,可能如下所示:
const config = {
auth: {
clientId: registered_power_bi_client_id,
authority: https://login.microsoftonline.com/your_tenant_app_id,
},
cache: {
cacheLocation: 'localStorage',
storeAuthStateInCookie: false,
},
};
export const instance = new PublicClientApplication(config);
const loginRequest: PopupRequest = {
scopes: [power_bi_scope], // might look like this https://analysis.windows.net/powerbi/api/Report.Read.All
account: currently_logged_in_user,
redirectUri: redirect_uri, // page when
};
export const getPowerBiToken = async () => {
let token;
try {
await instance.initialize();
const res = await instance.acquireTokenSilent(loginRequest);
token = res?.accessToken
} catch {
const res = await instance.acquireTokenPopup(loginRequest);
token = res?.accessToken;
}
return token;
};
然后
getPowerBiToken
函数您可以在组件逻辑中使用。
如果您第一次登录该应用程序,则会出现弹出窗口,要求登录。成功登录后,您应该获得正确的访问令牌。
之后,应使用
acquireTokenSilent
方法静默获取令牌。