如何将 azure 广告集成到在 azure 中也使用 REST API 的 React Web 应用程序 [英] How to integrate azure ad into a react web app that consumes a REST API in azure too

查看:16
本文介绍了如何将 azure 广告集成到在 azure 中也使用 REST API 的 React Web 应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

我的代码如下:adalconfig.js

import { AuthenticationContext, adalFetch, withAdalLogin } from 'react-adal';导出常量 adalConfig = {租户:'mytenantguid',clientId: 'myappguid',端点:{api: '14d71d65-f596-4eae-be30-27f079bf8d4b',},缓存位置:'localStorage',};导出 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

从'react'导入反应;从 'react-dom' 导入 ReactDOM;从 './dashApp' 导入 DashApp;从'./registerServiceWorker'导入registerServiceWorker;导入antd/dist/antd.css";从'react-adal'导入{runWithAdal};从'./adalConfig'导入{ authContext };常量 DO_NOT_LOGIN = 假;runWithAdal(authContext, () => {ReactDOM.render(, document.getElementById('root'));//热模块更换 API如果(module.hot){module.hot.accept('./dashApp.js', () => {const NextApp = require('./dashApp').default;ReactDOM.render(<NextApp/>, document.getElementById('root'));});}},DO_NOT_LOGIN);注册服务工作者();

dashapp.js

从react"导入反应;从react-redux"导入 { Provider };从./redux/store"导入 { 商店,历史 };从./router"导入 PublicRoutes;从样式化组件"导入 { ThemeProvider };从antd"导入 { LocaleProvider };从react-intl"导入 { IntlProvider };从./settings/themes"导入主题;从./languageProvider"导入 AppLocale;导入配置,{获取当前语言} 来自./containers/LanguageSwitcher/config";从./settings"导入{主题配置};从./dashAppStyle"导入 DashAppHolder;从./redux/boot"导入引导;常量 currentAppLocale =AppLocale[getCurrentLanguage(config.defaultLanguage || "english").locale];const DashApp = () =>(<LocaleProvider locale={currentAppLocale.antd}><国际提供者locale={currentAppLocale.locale}消息={currentAppLocale.messages}><ThemeProvider 主题={themes[themeConfig.theme]}><DashAppHolder><提供者商店={商店}><PublicRoutes 历史={history}/></提供者></DashAppHolder></主题提供者></国际提供者></LocaleProvider>);引导().then(() => DashApp()).catch(error => console.error(error));导出默认 DashApp;导出 { AppLocale };

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

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

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

我找到了这个,看起来我在找什么,但我不确定如何将它集成到我上面的现有代码中

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

更新:对于潜在的读者

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

解决方案

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

  1. 使用 ADAL 实例 (authContext) 获取由 resourceGuiId 标识的资源的访问令牌.
  2. 将此访问令牌添加到 options 对象的 headers 字段(如果未提供,则创建一个).
  3. 调用给定的fetch"方法,传入 urloptions 对象作为参数.

adalApiFetch 方法(您已在 adalConfig.js 中定义)只需使用 adalConfig 中标识的资源调用 adalFetch.端点.api.

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

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

import { AuthenticationContext, adalFetch, withAdalLogin } from 'react-adal';导出常量 adalConfig = {租户:'{tenant-id-or-domain-name}',clientId: '{app-id-of-native-client-app}',端点:{api: 'https://graph.microsoft.com'//<-- 受 Azure AD 保护的 API},缓存位置:'localStorage',};导出 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 使用 react-adal 中的 runWithAdal 方法包装 indexApp.js,确保用户在加载 indexApp.js 之前使用 Azure AD 签名:

import { runWithAdal } from 'react-adal';从'./adalConfig'导入{ authContext };常量 DO_NOT_LOGIN = 假;runWithAdal(authContext, () => {//eslint-disable-next-line要求('./indexApp.js');},DO_NOT_LOGIN);

indexApp.js 只是加载和渲染一个 App 的实例,这里没什么特别的:

从'react'导入反应;从 'react-dom' 导入 ReactDOM;导入'./index.css';从'./App'导入应用程序;从'./registerServiceWorker'导入registerServiceWorker;ReactDOM.render(<App/>, document.getElementById('root'));注册服务工作者();

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

  • 我们定义了一个 state 值.在本例中,它被称为 apiResponse,因为我们只是显示原始 API 响应,但当然您可以随意命名此状态(或具有多个状态值).
  • componentDidMount 期间(在元素在 DOM 中可用之后运行),我们调用 adalApiFetch.我们传入 fetch(来自 Fetch API 作为 fetch 参数,以及我们要发出的 REST 请求的端点(在本例中为 Microsoft Graph 中的 /me 端点):
  • render 方法中,我们只是在 <pre> 元素中显示此状态值.

import React, { Component } from 'react';从'./adalConfig'导入{ adalApiFetch };类应用扩展组件{状态 = {api响应:''};组件DidMount() {//我们使用 Fetch 作为要调用的方法,以及/me 端点//从 Microsoft Graph 作为 REST API 请求发出.adalApiFetch(fetch, 'https://graph.microsoft.com/v1.0/me', {}).then((响应) => {//这是您处理 API 响应的地方.在这种情况下,我们//将响应解释为 JSON,然后调用 `setState`//漂亮打印的 JSON 字符串化对象.响应.json().then((responseJson) => {this.setState({ apiResponse: JSON.stringify(responseJson, null, 2) })});}).catch((错误) => {//不要忘记处理错误!控制台.错误(错误);})}使成为() {返回 (

<p>API 响应:</p><pre>{ this.state.apiResponse }</pre></div>);}}导出默认应用程序;

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.

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

My code is as follows: 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

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

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.

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.

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

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

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/

解决方案

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:

  1. Use the ADAL instance (authContext) to obtain an access token for the resource identified by resourceGuiId.
  2. Add this access token to the headers field of the options object (or create one if it wasn't provided).
  3. Call the given "fetch" method passing in url and the options object as parameters.

The adalApiFetch method (which you have defined in adalConfig.js) simply calls adalFetch with the resource identified in 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.

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

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.js wraps indexApp.js with the runWithAdal method from react-adal, which ensures the user is signed with Azure AD before loading 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.js simply loads and renders an instance of App, nothing fancy here:

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.js is a simple component where the magic happens:

  • We define a state value. In this case, it's called apiResponse since 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 API as the fetch parameter, and the endpoint for the REST request we want to make (the /me endpoint in Microsoft Graph, in this case):
  • In the render method, we simply display this state value in a <pre> element.

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;

这篇关于如何将 azure 广告集成到在 azure 中也使用 REST API 的 React Web 应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆