javascript 如何将 azure 广告集成到使用 azure 中的 REST API 的 React Web 应用程序中

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/50305568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 09:01:09  来源:igfitidea点击:

How to integrate azure ad into a react web app that consumes a REST API in azure too

javascriptreactjsazure-active-directoryadaladal.js

提问by Luis Valencia

I have one web app which is React, and I already configured Azure AD Authentication for the web app itself. Its 100% Client site app, no server side components.

我有一个名为 React 的 Web 应用程序,并且我已经为 Web 应用程序本身配置了 Azure AD 身份验证。它的 100% 客户端站点应用程序,没有服务器端组件。

I used this component: https://github.com/salvoravida/react-adal

我使用了这个组件:https: //github.com/salvoravida/react-adal

My code is as follows: adalconfig.js

我的代码如下:adalconfig.js

import { AuthenticationContext, adalFetch, withAdalLogin } from 'react-adal';

export const adalConfig = {
  tenant: 'mytenantguid',
  clientId: 'myappguid',
  endpoints: {
    api: '14d71d65-f596-4eae-be30-27f079bf8d4b',
  },
  cacheLocation: 'localStorage',
};

export const authContext = new AuthenticationContext(adalConfig);

export const adalApiFetch = (fetch, url, options) =>
  adalFetch(authContext, adalConfig.endpoints.api, fetch, url, options);

export const withAdalLoginApi = withAdalLogin(authContext, adalConfig.endpoints.api);

index.js

索引.js

import React from 'react';
import ReactDOM from 'react-dom';
import DashApp from './dashApp';
import registerServiceWorker from './registerServiceWorker';
import 'antd/dist/antd.css';

import { runWithAdal } from 'react-adal';
import { authContext } from './adalConfig';

const DO_NOT_LOGIN = false;

runWithAdal(authContext, () => {

  ReactDOM.render(<DashApp />, document.getElementById('root'));

  // Hot Module Replacement API
  if (module.hot) {
    module.hot.accept('./dashApp.js', () => {
      const NextApp = require('./dashApp').default;
      ReactDOM.render(<NextApp />, document.getElementById('root'));
    });
  }

},DO_NOT_LOGIN);


registerServiceWorker();

dashapp.js

dashapp.js

import React from "react";
import { Provider } from "react-redux";
import { store, history } from "./redux/store";
import PublicRoutes from "./router";
import { ThemeProvider } from "styled-components";
import { LocaleProvider } from "antd";
import { IntlProvider } from "react-intl";
import themes from "./settings/themes";
import AppLocale from "./languageProvider";
import config, {
  getCurrentLanguage
} from "./containers/LanguageSwitcher/config";
import { themeConfig } from "./settings";
import DashAppHolder from "./dashAppStyle";
import Boot from "./redux/boot";

const currentAppLocale =
  AppLocale[getCurrentLanguage(config.defaultLanguage || "english").locale];


const DashApp = () => (
  <LocaleProvider locale={currentAppLocale.antd}>
    <IntlProvider
      locale={currentAppLocale.locale}
      messages={currentAppLocale.messages}
    >
      <ThemeProvider theme={themes[themeConfig.theme]}>
        <DashAppHolder>
          <Provider store={store}>
            <PublicRoutes history={history} />
          </Provider>
        </DashAppHolder>
      </ThemeProvider>
    </IntlProvider>
  </LocaleProvider>
);
Boot()
  .then(() => DashApp())
  .catch(error => console.error(error));

export default DashApp;
export { AppLocale };

Until that point everything works fine, when the user is not authenticated its redirected to login.live.com for authentication and then its redirected back.

在那之前,一切正常,当用户未通过身份验证时,将其重定向到 login.live.com 进行身份验证,然后重定向回来。

However I also created another azure webapp for hosting a REST API, that REST API is already configured in Azure AD, so that users that try to use the rest will need to be authenticated.

但是,我还创建了另一个用于托管 REST API 的 azure webapp,该 REST API 已在 Azure AD 中配置,因此尝试使用其余 API 的用户需要进行身份验证。

Now the question is: How do I setup my client side APP to consume REST API which is protected by Azure AD.?

现在的问题是:如何设置我的客户端 APP 以使用受 Azure AD 保护的 REST API。?

I found this and looks what I am looking for, but I am not sure how to integrate this into my existing code above

我找到了这个并寻找我正在寻找的东西,但我不确定如何将它集成到我上面的现有代码中

https://github.com/AzureAD/azure-activedirectory-library-for-js/issues/481

https://github.com/AzureAD/azure-activedirectory-library-for-js/issues/481

Update: For potential readers

更新:对于潜在读者

This answer plus the instructions on this url to configure App registrations helped me to solve the problem: https://blog.ithinksharepoint.com/2016/05/16/dev-diary-s01e06-azure-mvc-web-api-angular-and-adal-js-and-401s/

这个答案加上这个 url 上的说明来配置应用程序注册帮助我解决了这个问题:https: //blog.ithinksharepoint.com/2016/05/16/dev-diary-s01e06-azure-mvc-web-api-angular -and-adal-js-and-401s/

采纳答案by Philippe Signoret

The key here is adalApiFetch, defined in adalConfig.js. As you can see, it's a simple wrapper around adalFetch. This method (defined in react-adal) receives an ADAL instance (authContext), a resource identifier (resourceGuiId), a method (fetch), a URL (url) and an object (options). The method does the following:

这里的关键是adalApiFetch,定义在adalConfig.js. 如您所见,它是一个简单的adalFetch. 该方法(在 中定义react-adal)接收 ADAL 实例 ( authContext)、资源标识符 ( resourceGuiId)、方法 ( fetch)、 URL ( url) 和对象 ( options)。该方法执行以下操作:

  1. Use the ADAL instance (authContext) to obtain an access token for the resource identified by resourceGuiId.
  2. Add this access token to the headersfield of the optionsobject (or create one if it wasn't provided).
  3. Call the given "fetch" method passing in urland the optionsobject as parameters.
  1. 使用 ADAL 实例 ( authContext) 获取由 标识的资源的访问令牌resourceGuiId
  2. 将此访问令牌添加到对象的headers字段options(如果未提供,则创建一个)。
  3. 调用传入的给定“fetch”方法urloptions对象作为参数。

The adalApiFetchmethod (which you have defined in adalConfig.js) simply calls adalFetchwith the resource identified in adalConfig.endpoints.api.

adalApiFetch方法(您已在 中定义adalConfig.js)仅adalFetch使用 中标识的资源进行调用adalConfig.endpoints.api

Ok, so how do you use all of this to make a REST request, and consume the response in your React app? Let's use an example. In the following example, we will be using the Microsoft Graph API as the Azure AD-protected REST API. We will be identifying it by it's friendly identifier URI ("https://graph.microsoft.com"), but just keep in mind that that could just as well be the Guid app ID.

好的,那么您如何使用所有这些来发出 REST 请求,并在您的 React 应用程序中使用响应?让我们举一个例子。在以下示例中,我们将使用 Microsoft Graph API 作为 Azure AD 保护的 REST API。我们将通过它的友好标识符 URI(“ https://graph.microsoft.com”)来识别它,但请记住,这也可能是 Guid 应用程序 ID。

adalConfig.jsdefines the ADAL configuration, and exports a couple helper methods:

adalConfig.js定义了 ADAL 配置,并导出了几个辅助方法:

import { AuthenticationContext, adalFetch, withAdalLogin } from 'react-adal';

export const adalConfig = {
tenant: '{tenant-id-or-domain-name}',
clientId: '{app-id-of-native-client-app}',
endpoints: {
    api: 'https://graph.microsoft.com' // <-- The Azure AD-protected API
},
cacheLocation: 'localStorage',
};

export const authContext = new AuthenticationContext(adalConfig);

export const adalApiFetch = (fetch, url, options) =>
adalFetch(authContext, adalConfig.endpoints.api, fetch, url, options);

export const withAdalLoginApi = withAdalLogin(authContext, adalConfig.endpoints.api);

index.jswraps indexApp.jswith the runWithAdalmethod from react-adal, which ensures the user is signed with Azure AD before loading indexApp.js:

index.jsindexApp.js使用runWithAdalfrom 方法包装react-adal,确保用户在加载之前使用 Azure AD 签名indexApp.js

import { runWithAdal } from 'react-adal';
import { authContext } from './adalConfig';

const DO_NOT_LOGIN = false;

runWithAdal(authContext, () => {

// eslint-disable-next-line
require('./indexApp.js');

},DO_NOT_LOGIN);

indexApp.jssimply loads and renders an instance of App, nothing fancy here:

indexApp.js只是加载和呈现 的实例App,这里没什么特别的:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import registerServiceWorker from './registerServiceWorker';

ReactDOM.render(<App />, document.getElementById('root'));
registerServiceWorker();

App.jsis a simple component where the magic happens:

App.js是一个神奇的简单组件:

  • We define a statevalue. In this case, it's called apiResponsesince we're just displaying the raw API response, but of course you could name this state whatever you wanted (or have multiple state values).
  • During componentDidMount(which is run after the element is available in the DOM), we make a call to the adalApiFetch. We pass in fetch(from the Fetch APIas the fetchparameter, and the endpoint for the REST request we want to make (the /meendpoint in Microsoft Graph, in this case):
  • In the rendermethod, we simply display this state value in a <pre>element.
  • 我们定义一个state值。在这种情况下,它被调用是apiResponse因为我们只是显示原始 API 响应,但当然您可以随意命名此状态(或具有多个状态值)。
  • 在期间componentDidMount(在元素在 DOM 中可用之后运行),我们调用adalApiFetch. 我们传入fetch(从Fetch API作为fetch参数,以及我们想要发出的 REST 请求的/me端点(在本例中为 Microsoft Graph 中的端点):
  • render方法中,我们只是在一个<pre>元素中显示这个状态值。
import React, { Component } from 'react';
import { adalApiFetch } from './adalConfig';

class App extends Component {

  state = {
    apiResponse: ''
  };

  componentDidMount() {

    // We're using Fetch as the method to be called, and the /me endpoint 
    // from Microsoft Graph as the REST API request to make.
    adalApiFetch(fetch, 'https://graph.microsoft.com/v1.0/me', {})
      .then((response) => {

        // This is where you deal with your API response. In this case, we            
        // interpret the response as JSON, and then call `setState` with the
        // pretty-printed JSON-stringified object.
        response.json()
          .then((responseJson) => {
            this.setState({ apiResponse: JSON.stringify(responseJson, null, 2) })
          });
      })
      .catch((error) => {

        // Don't forget to handle errors!
        console.error(error);
      })
  }

  render() {
    return (
      <div>
        <p>API response:</p>
        <pre>{ this.state.apiResponse }</pre>
      </div>
    );
  }
}

export default App;

回答by Janavi

I still had the issue with the config given above. I added on more config to the above and it worked. Hope it helps.

我仍然遇到上面给出的配置问题。我在上面添加了更多配置并且它起作用了。希望能帮助到你。

import { AuthenticationContext, adalFetch, withAdalLogin } from 'react-adal';

export const adalConfig = {
tenant: '{tenant-id-or-domain-name}',
clientId: '{app-id-of-native-client-app}',
endpoints: {
    api: 'https://graph.microsoft.com'
},
cacheLocation: 'localStorage',
extraQueryParameter: 'prompt=admin_consent'
};

export const authContext = new AuthenticationContext(adalConfig);