You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PowerBI嵌入场景中自动生成Azure AD访问令牌?

问题描述

我有一个React应用,借助powerbi-client-react库,采用**user-owns-data(又称embed-for-organization)**方式嵌入PowerBI服务报表,代码示例如下:

<PowerBIEmbed
  embedConfig = {{
    type: "report",   // Supported types: report, dashboard, tile, visual and qna
    id: "281839f6-4971-4ad3rtt",
    tokenType: models.TokenType.Aad,
    accessToken : "938orie90rekjd-9393"
    // ....some more properties here....
  }}
/>

其中,models对象从powerbi-client库导入,<PowerBIEmbed/>来自依赖包powerbi-client-react。

目前我获取Azure AD访问令牌的方式是:

  • 登录我的PowerBI账号
  • 打开浏览器控制台,执行copy(powerbiaccesstoken)获取令牌
  • 将令牌粘贴到代码中

该令牌有效期仅1小时,之后嵌入的报表会弹出PowerBI登录提示,我需要重复上述操作重新获取并粘贴令牌。我拥有一个可用于生成访问令牌的专用PowerBI Pro账号,请问是否有办法无需重复手动复制令牌,通过前端或后端的JavaScript代码在令牌过期前自动完成生成操作?

解决方案

后端自动生成令牌(推荐方案)

直接在前端处理账号凭据会导致信息泄露,生产环境必须采用后端生成令牌的方式,通过专用PowerBI Pro账号的凭据获取Azure AD令牌后,再提供给前端使用。以下是基于Node.js的实现示例:

步骤1:配置Azure AD应用

先在Azure AD中注册应用,授予它PowerBI Service的Delegated权限(如Report.Read.All、Dashboard.Read.All,按需选择),并获取以下信息:

  • 客户端ID(Client ID)
  • 客户端密钥(Client Secret)
  • 租户ID(Tenant ID)
  • 专用PowerBI Pro账号的用户名和密码

步骤2:Node.js后端代码示例

使用@azure/msal-node库实现令牌获取逻辑,并暴露接口供前端调用:

const { ConfidentialClientApplication } = require('@azure/msal-node');
const express = require('express');
const app = express();

// Azure AD配置参数
const msalConfig = {
  auth: {
    clientId: "YOUR_AZURE_AD_CLIENT_ID",
    authority: "https://login.microsoftonline.com/YOUR_TENANT_ID",
    clientSecret: "YOUR_AZURE_AD_CLIENT_SECRET"
  }
};

const pca = new ConfidentialClientApplication(msalConfig);

// 获取PowerBI访问令牌
async function getPowerBIEmbedToken() {
  const tokenRequest = {
    scopes: ["https://analysis.windows.net/powerbi/api/.default"],
    username: "YOUR_POWERBI_PRO_USERNAME",
    password: "YOUR_POWERBI_PRO_PASSWORD"
  };

  try {
    const response = await pca.acquireTokenByUsernamePassword(tokenRequest);
    return response.accessToken;
  } catch (error) {
    console.error("令牌获取失败:", error);
    throw error;
  }
}

// 暴露接口给前端
app.get('/api/get-powerbi-token', async (req, res) => {
  try {
    const token = await getPowerBIEmbedToken();
    res.json({ accessToken: token });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

app.listen(3001, () => console.log("后端服务运行在3001端口"));

步骤3:React前端调用接口并自动刷新令牌

在React应用中,初始化时获取令牌,并设置定时任务在令牌过期前10分钟刷新:

import { useState, useEffect } from 'react';
import { PowerBIEmbed } from 'powerbi-client-react';
import { models } from 'powerbi-client';

function PowerBIReport() {
  const [accessToken, setAccessToken] = useState("");

  // 调用后端接口获取令牌
  const fetchToken = async () => {
    const response = await fetch('http://localhost:3001/api/get-powerbi-token');
    const data = await response.json();
    setAccessToken(data.accessToken);
  };

  // 初始化获取令牌,每50分钟刷新一次
  useEffect(() => {
    fetchToken();
    const refreshInterval = setInterval(fetchToken, 50 * 60 * 1000);
    return () => clearInterval(refreshInterval);
  }, []);

  const embedConfig = {
    type: "report",
    id: "281839f6-4971-4ad3rtt",
    tokenType: models.TokenType.Aad,
    accessToken: accessToken,
    // 其他配置项
  };

  return accessToken ? <PowerBIEmbed embedConfig={embedConfig} /> : <div>加载中...</div>;
}

export default PowerBIReport;

前端直接获取令牌(仅适合测试环境)

如果仅用于测试,可以使用@azure/msal-browser库在前端直接获取,但此方式会暴露账号凭据,绝对禁止用于生产环境:

import { PublicClientApplication } from '@azure/msal-browser';
import { useState, useEffect } from 'react';
import { PowerBIEmbed } from 'powerbi-client-react';
import { models } from 'powerbi-client';

const pca = new PublicClientApplication({
  auth: {
    clientId: "YOUR_AZURE_AD_CLIENT_ID",
    authority: "https://login.microsoftonline.com/YOUR_TENANT_ID"
  }
});

function PowerBIReport() {
  const [accessToken, setAccessToken] = useState("");

  const fetchToken = async () => {
    try {
      const response = await pca.acquireTokenByUsernamePassword({
        scopes: ["https://analysis.windows.net/powerbi/api/.default"],
        username: "YOUR_POWERBI_PRO_USERNAME",
        password: "YOUR_POWERBI_PRO_PASSWORD"
      });
      setAccessToken(response.accessToken);
    } catch (err) {
      console.error(err);
    }
  };

  useEffect(() => {
    fetchToken();
    const refreshInterval = setInterval(fetchToken, 50 * 60 * 1000);
    return () => clearInterval(refreshInterval);
  }, []);

  const embedConfig = {
    type: "report",
    id: "281839f6-4971-4ad3rtt",
    tokenType: models.TokenType.Aad,
    accessToken: accessToken,
    // 其他配置项
  };

  return accessToken ? <PowerBIEmbed embedConfig={embedConfig} /> : <div>加载中...</div>;
}

export default PowerBIReport;

内容的提问来源于stack exchange,提问作者navinrangar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 09:45:42