DEV Community

Cover image for Embedding a Power BI Dashboard: A Secure and Simple Solution
cristian velasquez
cristian velasquez

Posted on

1

Embedding a Power BI Dashboard: A Secure and Simple Solution

Embedding Power BI dashboards in a web application is a powerful way to share insights securely with users. In this tutorial, I'll guide you through the steps to set up a basic solution using Express for the backend and React for the frontend, while covering essential configurations in Azure and Power BI.

1. Configurations in Azure

To embed Power BI reports, you need to register an app in Azure Active Directory:

  1. Register an Application:

    • Go to the Azure portal → Azure Active Directory → App registrations → New registration.
    • Enter a name (e.g., "PowerBIEmbedApp") and set the Redirect URI to your frontend's base URL.
  2. API Permissions:

    • Add permissions for Power BI Service (Delegated and Application).
    • Grant admin consent for the permissions.
  3. Client Secret:

    • Create a new client secret under Certificates & secrets.
    • Note down the Application (client) ID, Directory (tenant) ID, and Client Secret.

2. Configurations in Power BI

  1. Enable Embed Token Generation:

    • Log in to the Power BI Service → Admin Portal → Tenant Settings.
    • Enable "Allow service principals to use Power BI APIs".
  2. Assign Workspace Access:

    • Add the service principal (registered app) to the Power BI workspace as an Admin or Member.
  3. Obtain Dashboard/Report IDs:

    • Note down the workspace, dashboard, and report IDs of the content you want to embed.

3. Backend: Express Setup

The backend is responsible for generating an embedded token for the dashboard.

Authentication process for PBI embeeding

Install dependencies:

npm install express axios dotenv
Enter fullscreen mode Exit fullscreen mode

Backend Code:

const express = require('express');
const axios = require('axios');
const dotenv = require('dotenv');
dotenv.config();

const app = express();
app.use(express.json());

// Environment variables from .env
const {
  TENANT_ID,
  CLIENT_ID,
  CLIENT_SECRET,
  WORKSPACE_ID,
  REPORT_ID,
} = process.env;

const POWER_BI_AUTH_URL = `https://login.microsoftonline.com/${TENANT_ID}/oauth2/v2.0/token`;

app.get('/api/getEmbedToken', async (req, res) => {
  try {
    // Get Access Token
    const authResponse = await axios.post(POWER_BI_AUTH_URL, new URLSearchParams({
      grant_type: 'client_credentials',
      client_id: CLIENT_ID,
      client_secret: CLIENT_SECRET,
      scope: 'https://analysis.windows.net/powerbi/api/.default',
    }));

    const accessToken = authResponse.data.access_token;

    // Get Embed Token
    const embedResponse = await axios.post(
      `https://api.powerbi.com/v1.0/myorg/groups/${WORKSPACE_ID}/reports/${REPORT_ID}/GenerateToken`,
      { accessLevel: 'View' },
      { headers: { Authorization: `Bearer ${accessToken}` } }
    );

    res.json(embedResponse.data);
  } catch (error) {
    console.error(error.message);
    res.status(500).send('Error generating embed token');
  }
});

const PORT = 5000;
app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
Enter fullscreen mode Exit fullscreen mode

4. Frontend: React Setup

Install dependencies:

npm install react powerbi-client axios
Enter fullscreen mode Exit fullscreen mode

Frontend Code:

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

const Dashboard = () => {
  const [embedConfig, setEmbedConfig] = useState(null);

  useEffect(() => {
    const fetchEmbedToken = async () => {
      try {
        const response = await axios.get('http://localhost:5000/api/getEmbedToken');
        setEmbedConfig({
          type: 'report',
          tokenType: 1,
          accessToken: response.data.token,
          embedUrl: response.data.embedUrl,
          settings: { panes: { filters: { visible: false } } },
        });
      } catch (error) {
        console.error('Error fetching embed token:', error);
      }
    };
    fetchEmbedToken();
  }, []);

  if (!embedConfig) return <div>Loading...</div>;

  return (
    <PowerBIEmbed
      embedConfig={embedConfig}
      cssClassName="dashboard-embed"
    />
  );
};

export default Dashboard;
Enter fullscreen mode Exit fullscreen mode

5. Final Steps

  • Run the backend: node server.js.
  • Run the frontend: npm start (assuming Create React App or similar setup).
  • Visit your frontend application to see the embedded Power BI dashboard.

Takeaways

This setup provides a secure and simple way to embed Power BI dashboards. For production, consider:

  • Storing sensitive environment variables securely (e.g., using Azure Key Vault).
  • Implementing better error handling and logging.
  • Securing API routes with authentication/authorization.

For more information, I invite you to check out how I implemented this in a real-world scenario in this article. Additionally, you can find the implementation using Next.js in this repository, adapted to a modern and scalable stack.

Feel free to customize this solution based on your project's needs!

Thanks for reading !! 😊😊

Image of Docusign

Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more

Top comments (0)

Eliminate Context Switching and Maximize Productivity

Pieces.app

Pieces Copilot is your personalized workflow assistant, working alongside your favorite apps. Ask questions about entire repositories, generate contextualized code, save and reuse useful snippets, and streamline your development process.

Learn more

👋 Kindness is contagious

Explore a sea of insights with this enlightening post, highly esteemed within the nurturing DEV Community. Coders of all stripes are invited to participate and contribute to our shared knowledge.

Expressing gratitude with a simple "thank you" can make a big impact. Leave your thanks in the comments!

On DEV, exchanging ideas smooths our way and strengthens our community bonds. Found this useful? A quick note of thanks to the author can mean a lot.

Okay