Вопрос или проблема
Мне сейчас нужна помощь, если у кого-то есть опыт в встраивании отчетов Power BI в их Next-приложение? Я планирую, чтобы процесс входа в систему был бесшовным, чтобы пользователям не нужно было вводить свои учетные данные для просмотра отчета. Я смог встроить свой отчет Power BI, но он все еще вызывает всплывающее окно входа.
На данный момент у меня есть зарегистрированное приложение в Azure, я сделал необходимые разрешения для моего приложения на доступ к услугам Power BI (делегированные разрешения). А также предоставил разрешение на членство приложения в своем рабочем пространстве Power BI. Вот мой код, я заменил свои реальные идентификаторы на заполнители:
// serverAuthService.ts
// Этот файл предназначен для получения токена доступа для аутентификации серверной службы с помощью Power BI REST API
import { ConfidentialClientApplication } from "@azure/msal-node";
const msalConfig = {
auth: {
clientId: "<Мой-Клиент-ID>",
authority: "https://login.microsoftonline.com/<Tenant-ID>",
clientSecret: "<Секрет-клиента>",
},
};
const cca = new ConfidentialClientApplication(msalConfig);
export const acquireServerToken = async (): Promise<string | null> => {
try {
const result = await cca.acquireTokenByClientCredential({
scopes: ["https://analysis.windows.net/powerbi/api/.default"],
});
return result?.accessToken || null;
} catch (error) {
console.error("Ошибка при получении серверного токена:", error);
return null;
}
};
powerBIReports.tsx – компонент
// PowerBIReport.tsx
import React, { useEffect, useState } from "react";
import axios from "axios";
import { PowerBIEmbed } from "powerbi-client-react";
import { models } from "powerbi-client";
const PowerBIReport: React.FC = () => {
const [embedToken, setEmbedToken] = useState<string | null>(null);
useEffect(() => {
const fetchEmbedToken = async () => {
try {
const response = await axios.get("/api/getPowerBIEmbedToken");
console.log("TOKEN AXIOS: ", response.data.embedToken);
setEmbedToken(response.data.embedToken);
} catch (error) {
console.error("Не удалось получить токен встраивания:", error);
}
};
fetchEmbedToken();
}, []);
if (!embedToken) {
return <div>Загрузка отчета Power BI...</div>;
}
return (
<PowerBIEmbed
embedConfig={{
type: "report",
id: "<ID-отчета>",
embedUrl: "https://app.powerbi.com/reportEmbed?reportId=<ID-отчета>&groupId=<ID-группы>&w=2&config=eyJjbHVzdGVyVXJsIjoiaHR0cHM6Ly9XQUJJLVNPVVRILUVBU1QtQVNJQS1DLVBSSU1BUlktcmVkaXJlY3QuYW5hbHlzaXMud2luZG93cy5uZXQiLCJlbWJlZEZlYXR1cmVzIjp7InVzYWdlTWV0cmljc1ZOZXh0Ijp0cnVlfX0%3d",
accessToken: embedToken,
tokenType: models.TokenType.Embed,
settings: {
panes: {
filters: {
visible: false,
},
},
navContentPaneEnabled: true,
},
}}
cssClassName="report-container"
/>
);
};
export default PowerBIReport;
getPowerBIEmbedToken.ts
// pages/api/getPowerBIEmbedToken.ts
import type { NextApiRequest, NextApiResponse } from "next";
import { acquireServerToken } from "../../components/serverAuthService"; // Настройте этот путь
import axios from "axios";
import {jwtDecode} from "jwt-decode";
export default async (req: NextApiRequest, res: NextApiResponse) => {
try {
// Получите токен доступа с помощью MSAL Node
const accessToken = await acquireServerToken(); // Это предназначено для аутентификации приложения
console.log("Токен доступа:", accessToken);
// Декодируйте токен, чтобы проверить аудиторию
if(accessToken){
const decodedToken: any = jwtDecode(accessToken);
console.log("Декодированная аудитория токена (aud):", decodedToken.aud);
}
if (!accessToken) {
return res.status(500).json({ error: "Не удалось получить токен доступа" });
}
console.log("Это токен доступа: ", accessToken);
// Вызовите Power BI REST API, чтобы получить токен встраивания
const embedResponse = await axios.post(
'https://api.powerbi.com/v1.0/myorg/groups/<Groups-ID>/reports/<Reports-ID>/GenerateToken',
{
accessLevel: "View", // Настройте уровень доступа при необходимости
},
{
headers: {
Authorization: `Bearer ${accessToken}`,
"Content-Type": "application/json",
},
}
);
return res.status(200).json({ embedToken: embedResponse.data.token });
} catch (error) {
console.error("Ошибка при получении токена Power BI для встраивания:", error);
return res.status(500).json({ error: "Не удалось получить токен встраивания Power BI" });
}
};
В ходе своих исследований я обнаружил, что вам также необходимо разрешить права приложения (хотя мне нужно подтверждение на это), но он показывает только Tenant, чтобы убедиться, что я предоставил изображение здесь: Разрешение приложения
Ответ или решение
Конечно! Вот развернутый ответ на вопрос о бесшовном встраивании отчета Power BI в приложение Next. Я постараюсь покрыть все аспекты, которые могут помочь вам решить проблему с отображением входной формы.
Решение проблемы с аутентификацией при встраивании Power BI в приложение Next.js
Вы на правильном пути, но для того, чтобы обеспечить бесшовный доступ к отчетам Power BI без запроса логина, вам необходимо удостовериться, что вы настроили все необходимые разрешения и корректно используете токены доступа.
Шаги для достижения бесшовного доступа
-
Регистрация приложения в Azure:
Убедитесь, что ваше приложение зарегистрировано в Azure AD. Вам необходимо знать следующее:- Client ID (Идентификатор клиента)
- Client Secret (Секрет клиента)
- Tenant ID (Идентификатор арендатора)
-
Настройка разрешений:
Включите как делегированные (Delegated Permissions), так и приложенческие (Application Permissions) разрешения для вашего приложения, чтобы обеспечить возможность доступа к отчётам.
Убедитесь, что вы предоставили необходимые разрешения на уровне API Power BI, такие как:Report.Read.All
Dataset.Read.All
-
Использование серверного токена:
Ваш код для получения токена выглядит правильно. Убедитесь, что вы вызываете методacquireTokenByClientCredential
с правильными скоупами (scopes
), чтобы получить токен для доступа к API Power BI. -
Генерация токена встраивания:
Когда вы получаете токен доступа, используйте его для получения токена встраивания. Убедитесь, что у вас есть правильный ID группы (Group ID) и ID отчета (Report ID):const embedResponse = await axios.post( 'https://api.powerbi.com/v1.0/myorg/groups/<Group-ID>/reports/<Report-ID>/GenerateToken', { accessLevel: "View", // Убедитесь, что уровень доступа установлен }, { headers: { Authorization: `Bearer ${accessToken}`, "Content-Type": "application/json", }, } );
-
Настройка CORS (если необходимо):
Если ваше приложение требует доступа к API из браузера, убедитесь, что CORS (Cross-Origin Resource Sharing) настроен правильно как на стороне API, так и на стороне приложения. -
Тестирование и отладка:
Убедитесь, что:- Токен доступа не истекает до того, как вы получаете токен встраивания.
- Вы проверяете все логируемые ошибки, чтобы выявить проблемы получения токена или доступа к API.
Пример конечного кода
Ваш код, который вы привели, в целом выглядит хорошо, но проверьте, чтобы он учитывал вышеописанные рекомендации. Например, как только вы получите токен встраивания в вашем обработчике API, передайте его на клиент:
// pages/api/getPowerBIEmbedToken.ts
if (embedResponse.data && embedResponse.data.token) {
return res.status(200).json({ embedToken: embedResponse.data.token });
}
После этого вы сможете использовать полученный embedToken
для отображения отчета Power BI без запроса на вход.
Кроме того, убедитесь, что у вашей группы и отчета есть доступ, и что они опубликованы для использования в вашем приложении.
Заключительные рекомендации
Наконец, профилируйте процесс выполнения вашего приложения, чтобы убедиться, что все работает эффективно и без задержек. Если после выполнения всех этих шагов проблема не исчезает, рассмотрите возможность обращения в службу поддержки Microsoft для получения дополнительной информации о вашем случае использования.
Мне бы хотелось знать, если у вас есть другие вопросы или вам необходимо более подробное руководство по какой-либо из тем!