Snooper_A
Snooper_A

Reputation: 145

ReactJS- BrowserAuthError: no_account_error: No account object provided to acquireTokenSilent and no active account has been set

I am trying to embed powerbi report to my reactjs web application but I am having trouble to get the embed access token. I am not using any kind of login function to my react web app, it is simple and it shows some details as header and trying show the powerbi report.

I always get error : BrowserAuthError: no_account_error: No account object provided to acquireTokenSilent and no active account has been set.Please call setActiveAccount or provide an account on the request.

Here is my code:

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

const msalConfig = {
  auth: {
    clientId: 'XXXXXXXXXXXXXXXXX',
    authority: 'https://login.microsoftonline.com/XXXXXXXXXXX',
  },
  cache: {
    cacheLocation: 'sessionStorage',
    storeAuthStateInCookie: false,
  },
};

const pca = new PublicClientApplication(msalConfig);

function EmbedReport() {
  const [accessToken, setAccessToken] = useState('');

  useEffect(() => {
    pca.handleRedirectPromise().then((response) => {
      if (response !== null && response.account !== null) {
        // set active account
        pca.setActiveAccount(response.account);
        // acquire token
        pca.acquireTokenSilent({ scopes: ['https://analysis.windows.net/powerbi/api/.default'] })
          .then((response) => {
            setAccessToken(response.accessToken);
          })
          .catch((error) => {
            console.error(error);
          });
      }
    });
  }, []);

  return (
    <div>
      {accessToken ? (
        <PowerBIEmbed
          embedConfig={{
            type: 'report',
            id: 'XXXXXXXX',
            embedUrl: 'https://app.powerbi.com/reportEmbed?reportId=XXXXXXXXX',
            accessToken: accessToken,
            tokenType: models.TokenType.Embed,
            settings: {
              panes: {
                filters: {
                  expanded: false,
                  visible: false,
                },
              },
              background: models.BackgroundType.Transparent,
            },
          }}
        />
      ) : (
        <div>Loading...</div>
      )}
    </div>
  );
}

export default EmbedReport;

Also i found that pca.handleRedirectPromise().then((response) => { gives responsenull always.

more info: I have created app registration through azure portal. and to that new registration i have selected both Access token and Id tokes I have also created secrets with the app registration, Also i have granted the Api permission for PowerBi service Read.Readwrite.all

I am not able to find what i am missing and what do i need to do inorder to get the accesstoken. Could you hlep me to get the accesstoken so that i can display powerBi report in my react web app.

Upvotes: 3

Views: 4007

Answers (1)

Sridevi
Sridevi

Reputation: 22552

Note that, user needs to login atleast once to retrieve token using acquireTokenSilent method. You are facing that error as login function is not implemented in react web app.

If your use case is to get access token without user interaction, you can make use of username password flow.

I tried to reproduce the same in my environment and got below results:

I registered Azure AD application and granted API permissions as below:

enter image description here

I used below code and got access token successfully in response like this:

const getToken = async () => {
    const response = await fetch('https://login.microsoftonline.com/<tenantID>/oauth2/v2.0/token', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded'
      },
      body: new URLSearchParams({
        grant_type: 'password',
        client_id: 'c8deab7e-c74d-493e-b662-xxxxxxxx',
        client_secret: 'secret',
        scope: 'https://analysis.windows.net/powerbi/api/.default',
        username: '[email protected]',
        password: 'password'
      })
    });
  
    const data = await response.json();
    const accessToken = data.access_token;
    return accessToken;  
  };
  
  async function main() {
    const accessToken = await getToken();
    console.log("Access token:",accessToken);
  }
  
  main();

Response:

enter image description here

To confirm that, I decoded the above token in jwt.ms and got aud and scp claims like below:

enter image description here

When I used this token to retrieve reports via Postman, I got response successfully like this:

GET https://api.powerbi.com/v1.0/myorg/reports

Response:

enter image description here

Upvotes: 1

Related Questions