Skip to main content
cancel
Showing results for 
Search instead for 
Did you mean: 

Earn a 50% discount on the DP-600 certification exam by completing the Fabric 30 Days to Learn It challenge.

Reply
nkshriva
Frequent Visitor

Sign in screen comes after 60 mins even after fetching new token 10 mins before the expiration time

I am using embedded powerbi report in my react application. I am encountering a problem where in order to avoid the token expiry and sign in screen, I am fetching a new token 10 mins before the expiration time as per the following documentation:

 

https://learn.microsoft.com/en-us/javascript/api/overview/powerbi/refresh-token#refresh-the-access-t....

 

But even after setting the new token, the page shows the sign-in screen. Can anyone suggest any solution to this?

5 REPLIES 5
nkshriva
Frequent Visitor

Make sure the session refreshes and doesn't expire?

nkshriva_0-1709717068442.png

 

 

How to ensure the session is not expired in 10 mins of tab inactivity? I noticed if the tab is inactive for 10 mins, the session expires automatically and I have to click Refresh button.

 @v-yangliu-msft 

nkshriva
Frequent Visitor

@v-yangliu-msft Can you please help? I am stuck on this issue

v-yangliu-msft
Community Support
Community Support

Hi  @nkshriva ,

 

 

Can you provide me with the code you are currently configuring to refresh the token periodically? If the login page is still popping up even after the AAD token is refreshed, could you try to add an action to refresh the report frontend page every half hour/ or 40 minutes? Make sure the session refreshes and doesn't expire?

 

Best Regards,

Liu Yang

If this post helps, then please consider Accept it as the solution to help the other members find it more quickly.

This is the code which I am using to use embeded powerbi report.

import { PowerBIEmbed } from 'powerbi-client-react';
import { useEffect, useState, useRef } from 'react';
import { useDispatch } from 'react-redux';
import { models } from 'powerbi-client';
import axios from 'services';
import { useLocation } from 'react-router-dom';
import { ButtonGroup, ButtonToolbar } from 'react-bootstrap';
import Button from 'Components/Button';
import TextField from 'Components/TextField';
import Spinner from 'Components/Spinner';
import {
  setSecondaryHeader
} from 'store/slice/headerInfo';

const ReportOne = () => {
  const [report, setReport] = useState(null);
  const [config, setConfig] = useState({
    type: 'report',
    embedUrl: undefined,
    accessToken: undefined
  });
  const expirationTokenRef = useRef({});
  const reportRef = useRef({});
  const [edit, setEdit] = useState(false);
  const [name, setName] = useState('');
  const location = useLocation();
  const [isEmbedded, setIsEmbedded] = useState(false);
  const [isLoading, setIsLoading] = useState(true);
  // const [tokenExpiration, setTokenExpiration] = useState(null);
  const dispatch = useDispatch();

  useEffect(() => {
    console.log(location);
    setIsLoading(true);
    if (!location) return;
    dispatch(setSecondaryHeader({
      path: 'Reports_View Reports',
      route: '/reports/view_reports',
      section: 'Reports',
      subSection: 'View Reports'
    }));
    let postfix;
    if (location.pathname.includes('paginated')) {
      postfix = location.pathname.split('paginated/')[1];
    } else {
      // postfix = location.pathname.split('report/')[1];
      postfix = location.pathname.split('nonpaginated/')[1];
    }
    // const postfix = location.pathname.split('report/')[1];

    (async () => {
      const res = await axios.get(`pbi/report_embed_config?report_id=${postfix}`);
      console.log('expiration token', res.data?.expiration);
      const newConfig = {
        embedUrl: res.data?.report_details?.embed_url,
        accessToken: res.data?.token
      };
      if (location.pathname.includes('paginated')) {
        newConfig.uniqueId = res.data?.report_details?.report_id;
      } else {
        newConfig.id = res.data?.report_details?.report_id;
      }
      expirationTokenRef.current = res.data?.expiration;
      setConfig(newConfig);
      setIsEmbedded(true);
      setIsLoading(false);
    })();
  }, [location]);

  console.log(config);

  const updateToken = async reportId => {
    console.log('inside update token');
    // Generate a new embed token or refresh the user Azure AD access token
    const newAccessToken = await axios.get(`pbi/report_embed_config?report_id=${reportId}`);

    // Update the new token expiration time
    // setTokenExpiration(newAccessToken.data?.expiration);
    expirationTokenRef.current = newAccessToken.data?.expiration;

    // Set the new access token
    await reportRef.current.setAccessToken(newAccessToken.data?.token);
  };

  const checkTokenAndUpdate = reportId => {
    // Get the current time
    const currentTime = Date.now();
    const expiration = Date.parse(expirationTokenRef.current);

    // Time until token expiration in milliseconds
    const timeUntilExpiration = expiration - currentTime;
    const timeToUpdate = 10 * 60 * 1000;

    console.log(currentTime, expirationTokenRef.current, expiration, timeUntilExpiration, timeToUpdate);

    // Update the token if it is about to expired
    if (timeUntilExpiration <= timeToUpdate) {
      console.log(currentTime, expiration, timeUntilExpiration, timeToUpdate);
      let postfix;
      if (location.pathname.includes('paginated')) {
        postfix = location.pathname.split('paginated/')[1];
      } else {
        // postfix = location.pathname.split('report/')[1];
        postfix = location.pathname.split('nonpaginated/')[1];
      }
      console.log('Updating report access token');
      updateToken(postfix);
    }
  };

  useEffect(() => {
    if (!report) return;
    if (edit) {
      report.switchMode('edit');
    } else {
      report.switchMode('view');
    }
  }, [edit, report]);

  useEffect(() => {
    let postfix;
    if (location.pathname.includes('paginated')) {
      postfix = location.pathname.split('paginated/')[1];
    } else {
      // postfix = location.pathname.split('report/')[1];
      postfix = location.pathname.split('nonpaginated/')[1];
    }
    document.addEventListener('visibilitychange', function () {
      // Check the access token when the tab is visible
      console.log('visibilitychange');
      if (!document.hidden) {
        checkTokenAndUpdate(postfix);
      }
    });

    const tokenTimer = setInterval(() => {
      checkTokenAndUpdate(postfix);
    }, 60000);

    return () => {
      clearInterval(tokenTimer);
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);

  return (
    <>
      {isLoading && <Spinner type='content' />}
      {!isLoading &&
        <div>
          <ButtonToolbar
            className='justify-content-between'
            style={{ margin: 8 }}>
            <ButtonGroup className='me-2'>
              <Button
                variant='primary'
                style={{
                  display: 'none'
                }}
                onClick={() => setEdit(prev => !prev)}>
                {edit ? 'View' : 'Edit'}
              </Button>
            </ButtonGroup>
            {edit &&
            <ButtonToolbar>
              <ButtonGroup className='me-2'>
                <Button
                  style={{ display: 'none' }}
                  variant='primary'
                  onClick={() => report.save()}>
                  Save
                </Button>
              </ButtonGroup>
              <ButtonGroup className='me-2'>
                <TextField
                  className='me-2'
                  value={name}
                  onChange={e => setName(e.target.value)} />
              </ButtonGroup>
              <ButtonGroup className='me-2'>
                <Button
                  variant='primary'
                  disabled
                  onClick={() => {
                    report.saveAs({
                      name
                    });
                    setName('');
                  }}>
                  Save As
                </Button>
              </ButtonGroup>
            </ButtonToolbar>}
          </ButtonToolbar>
          {isEmbedded ? <PowerBIEmbed
            embedConfig={{
              ...config,
              type: 'report', // Supported types: report, dashboard, tile, visual, qna, paginated report and create
              tokenType: models.TokenType.Embed, // Use models.TokenType.Aad for SaaS embed
              settings: {
                panes: {
                  filters: {
                    expanded: false,
                    visible: false
                  }
                },
                background: models.BackgroundType.Transparent
              },
              permissions: models.Permissions.All
            // viewMode: models.viewMode.Edit
            }}
            cssClassName='reportClass'
            getEmbeddedComponent={embeddedReport => {
              setReport(embeddedReport);
              reportRef.current = embeddedReport;
            }}
          /> : null}
        </div>}
    </>
  );
};

export default ReportOne;

Helpful resources

Announcements
LearnSurvey

Fabric certifications survey

Certification feedback opportunity for the community.

PBI_APRIL_CAROUSEL1

Power BI Monthly Update - April 2024

Check out the April 2024 Power BI update to learn about new features.

April Fabric Community Update

Fabric Community Update - April 2024

Find out what's new and trending in the Fabric Community.