Не удалось загрузить данные ответа при попытке получить токен доступа из Azure с помощью JavaScript.

Я хочу получить токен доступа для своего зарегистрированного приложения в Azure. Для этого я написал фрагмент кода для работы с остальным API.

Это мой код:

<html>
<head>
  <title>Test</title>   
  <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
  <script src="https://secure.aadcdn.microsoftonline-p.com/lib/1.0.12/js/adal.min.js"></script>
  <script src="/static/powerbi.js"></script>
  <script src="https://unpkg.com/axios/dist/axios.min.js"></script>        
  </head>
<body>
  <div id="captionArea">
    <h1>Power BI Embed test</h1>
  </div>
  <div id="embedContainer" style="height:500px">
  </div> 
  <script>
    (function () {

    var reportId = 'xxxxxxxxxx'
    var groupId  = 'xxxxxxxxxx'   //workspace_id
    var datasetId = 'xxxxxxxxxx'
    
    
   var settings = {
  "url": "https://login.microsoftonline.com/common/oauth2/token",
  "method": "POST",
  "crossDomain": true,
  "dataType": 'jsonp',
  "timeout": 0,
  "headers": {
    "Content-Type": "application/x-www-form-urlencoded"
  },
  "data": {
    "client_id": "********",
    "username": "***",
    "password": "***",
    "grant_type": "password",
    "resource": "https://analysis.windows.net/powerbi/api"
  }
};

$.ajax(settings).done(function (response) {
  console.log(response);
}); 
}());
  </script>
</body>
</html>

и после этого я получил ответ. В консоли в разделе заголовка я получил статус: 200 и метод запроса: GET, но в моем коде метод запроса — POST, а в разделе ответов он показывает, что этот запрос не имеет доступных данных ответа:

введите здесь описание изображения

введите здесь описание изображения

Я не знаю, почему я не получаю никакого ответа и как мой метод запроса меняется с POST на GET?


person Akshay    schedule 17.12.2020    source источник
comment
Раньше у меня была та же идея, что и у вас, просто отправить запрос AJAX, чтобы получить токен доступа. И, конечно же, я потерпел неудачу. Я думаю, что этот документ поможет ты.   -  person tiny-wa    schedule 17.12.2020


Ответы (2)


<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>Document</title>
        <script src="js/msal.js"></script>
    </head>
    <body>
        <div style="font-size: 12px;">
            this sample used implicit grant flow to get access token
        </div>
            <div style="margin-top: 15px; background-color: #DDDDDD;">
                <button type="button" id="signIn" onclick="signIn()">Sign In</button>
                <button type="button" id="getAccessToken" onclick="getAzureAccessToken()">getAccessToken</button>
                <button type="button" id="accessApi" onclick="accessApi()">getApiResponse</button>
                <h5 class="card-title" id="welcomeMessage">Please sign-in to see your profile and read your mails</h5>
                <div>
                    <div>
                        accesstoken :
                        <div id="accesstoken">
                            
                        </div>
                    </div>
                    <div id="">
                        api response :
                        <div id="json">
                            
                        </div>
                    </div>
                </div>
            </div>
            <script type="text/javascript">
                const msalConfig = {
                    auth: {
                        clientId: "<applicationId>",
                        authority: "https://login.microsoftonline.com/<tenantId>",
                        redirectUri: "http://localhost:8848/Demo0819/new_file.html",
                    },
                    cache: {
                        cacheLocation: "sessionStorage", // This configures where your cache will be stored
                        storeAuthStateInCookie: false, // Set this to "true" if you are having issues on IE11 or Edge
                    }
                };
        
                const loginRequest = {
                    scopes: ["openid", "profile", "User.Read"]
                };
                //scope for getting accesstoken
                const AzureMgmtScops ={
                    scopes:["https://management.azure.com/user_impersonation"]
                }
                //used for calling api 
                const apiConf = {
                    endpoint:"https://management.azure.com/subscriptions/<subscriptionId>/providers/Microsoft.CostManagement/query?api-version=2019-11-01"
                };
                
                let accessToken = '';
                const myMSALObj = new Msal.UserAgentApplication(msalConfig);
        
                function signIn() {
                    myMSALObj.loginPopup(loginRequest)
                        .then(loginResponse => {
                            console.log("id_token acquired at: " + new Date().toString());
                            console.log(loginResponse);
        
                            if (myMSALObj.getAccount()) {
                                showWelcomeMessage(myMSALObj.getAccount());
                            }
                        }).catch(error => {
                            console.log(error);
                        });
                }
        
                function showWelcomeMessage(account) {
                    document.getElementById("welcomeMessage").innerHTML = `Welcome ${account.name}`;
                }
        
                function getAzureAccessToken(){
                    myMSALObj.acquireTokenSilent(AzureMgmtScops).then(tokenResponse => {
                        showAccesstoken(tokenResponse.accessToken)
                        accessToken = tokenResponse.accessToken;
                        // console.info("======the accesstoken is ======:"+tokenResponse.accessToken);
                        // callMSGraph(apiConf.endpoint, tokenResponse.accessToken, showResult);
                    }).catch(function (error) {
                         console.log(error);
                    })
                }
                
                function accessApi(){
                    callMSGraph(apiConf.endpoint, accessToken, showResult);
                }
        
                function callMSGraph(endpoint, token, callback) {
                    const data = {
                        "type": "Usage",
                        "timeframe": "MonthToDate",
                        "dataset": {
                            "granularity": "Daily",
                        }
                    }
                    const headers = new Headers();
                    const bearer = `Bearer ${token}`;
        
                    headers.append("Content-Type", "application/json");
                    headers.append("Authorization", bearer);
        
                    const options = {
                        body: JSON.stringify(data),
                        method: "POST",
                        headers: headers
                    };
        
                    console.log('request made to Graph API at: ' + new Date().toString());
        
                    fetch(endpoint, options)
                        .then(response => response.json())
                        .then(response => callback(response, endpoint))
                        .catch(error => console.log(error))
                }
                
                function showAccesstoken(data){
                    document.getElementById("accesstoken").innerHTML = JSON.stringify(data, null, 2);
                }
                
                function showResult(data){
                    document.getElementById("json").innerHTML = JSON.stringify(data, null, 2);
                }
            </script>
    </body>
</html>

=========ОБНОВЛЕНИЕ======

E.g.

Я хочу вызвать этот API для получения информации «https://api.powerbi.com/v1.0/myorg/groups», поэтому сначала добавьте разрешение API. введите здесь описание изображениявведите здесь описание изображения

Следующий шаг — получить токен доступа с этой областью. введите здесь описание изображения

С этим токеном доступа вызовите API, после чего он заработает. введите здесь описание изображения

person tiny-wa    schedule 18.12.2020
comment
Спасибо за ответ Tiny-wa. Используя это решение, я застрял на ошибке. Ошибка: InteractionRequiredAuthError: AADSTS65001: пользователь или администратор не дал согласия на использование приложения с идентификатором «xxxxxx» с именем «xxxxx powerBI Embed Test1». Отправьте интерактивный запрос авторизации для этого пользователя и ресурса. не могли бы вы мне помочь? - person Akshay; 26.12.2020
comment
В моем коде используется неявный поток предоставления для получения маркера доступа и вызова API, поэтому после создания рекламного приложения Azure мне также необходимо установить разрешение API и убедиться, что «токен доступа» отмечен в теге проверки подлинности. - person tiny-wa; 27.12.2020
comment
Я решил это. Необходимо добавить разрешение mail.read в Microsoft graph API. Просто войдите в свою учетную запись администратора и перейдите к регистрации приложения, затем выберите разрешения API и нажмите «Добавить разрешение». - person Akshay; 27.12.2020
comment
Я получил токен доступа, но этот токен доступа не смог получить токен для встраивания. Он возвращает 403 запрещено - person Akshay; 27.12.2020
comment
403 означает, что у вашего приложения нет разрешения на доступ к API. Итак, если вы хотите вызвать «powerbi-UserState.ReadWrite.All», вам нужно добавить это разрешение API, а затем получить токен доступа с этой областью действия, после чего вы можете это сделать. - person tiny-wa; 28.12.2020
comment
Любые идеи? Или подробнее? - person tiny-wa; 28.12.2020
comment
Эй, Тайни-ва, ты сделал мой день. Меня устраивает. Большое спасибо. - person Akshay; 28.12.2020
comment
Я рад это слышать, надеюсь, что ваша программа не содержит ошибок. хх, добрый день. - person tiny-wa; 28.12.2020

У вас есть тип данных как JSONP. Он просто создает элемент для получения данных, который должен быть запросом GET.

Ссылка: Отправка данных с использованием запроса POST в JSONP

Как использовать тип: POST в вызове jsonp ajax

Вы можете получить ответ, отправив запрос POST, а затем использовать полученный токен доступа для токена встраивания.

Что-то вроде ниже:

var getAccessToken = function {

  return new Promise(function(resolve, reject) {

    var url = 'https://login.microsoftonline.com/common/oauth2/token';

    var username = // Username of PowerBI "pro" account - stored in config
    var password = // Password of PowerBI "pro" account - stored in config
    var clientId = // Applicaton ID of app registered via Azure Active Directory - stored in config

    var headers = {
      'Content-Type' : 'application/x-www-form-urlencoded'
    };

    var formData = {
      grant_type:'password',
      client_id: clientId,
      resource:'https://analysis.windows.net/powerbi/api',
      scope:'openid',
      username:username,
      password:password
    };

    request.post({
      url:url,
      form:formData,
      headers:headers

    }, function(err, result, body) {
      if(err) return reject(err);
      var bodyObj = JSON.parse(body);
      resolve(bodyObj.access_token);
    })
  });
}

// -------------------------------------------

var getEmbedToken = function(accessToken, groupId, reportId) {

  return new Promise(function(resolve, reject) {

    var url = 'https://api.powerbi.com/v1.0/myorg/groups/' + groupId + '/reports/' + reportId + '/GenerateToken';

    var headers = {
      'Content-Type' : 'application/x-www-form-urlencoded',
      'Authorization' : 'Bearer ' + accessToken
    };

    var formData = {
      "accessLevel": "View"
    };

    request.post({
      url:url,
      form:formData,
      headers:headers

    }, function(err, result, body) {
      if(err) return reject(err);
      console.log(body)
      var bodyObj = JSON.parse(body);
      resolve(bodyObj.token);
    })
  })
}
person Satya V    schedule 17.12.2020
comment
Просто хотел проверить с вами, помогло ли вышеизложенное? - person Satya V; 22.12.2020
comment
Нет Сатья В. Это не помогает. - person Akshay; 27.12.2020