Реагировать на данные календаря Microsoft Outlook без сеанса входа в систему с помощью Hello.js - PullRequest
0 голосов
/ 11 января 2019

Я создаю календарь React, который принимает данные из «Календаря Microsoft Outlook» с использованием клиентского SDK JavaScript «hello.js» и Microsoft Graph (для настройки я также следовал этому руководству: https://docs.microsoft.com/en-us/graph/auth-register-app-v2).

Используя hello.login, мое приложение показывает календарь без проблем ... но, к сожалению, я должен показать его без сеанса входа в систему.

Это мой код:

class CalendarView extends Component {
  constructor(props) {
    super(props);

    hello.init({
      microsoft: {
        id: APP_ID,
        oauth: {
          version: 2,
          auth: 'https://login.microsoftonline.com/common/oauth2/v2.0/authorize',
        },
        scope_delim: ' ',
        form: false,
        scope: SCOPES,
      },
    });

    const { startDate, endDate } = this.props;

    this.state = {
      // events: [],
      startDataTime: startDate.toISOString(),
      endDataTime: endDate.toISOString(),
      token: hello('microsoft').getAuthResponse().access_token,
    };
  }

В этом другом компоненте я управляю Microsoft Graph Query:

class EventsList extends Component {
  constructor() {
    super();
    this.state = {
      events: [],
    };
  }

  componentWillReceiveProps(nextProps) {
    const { startDate, endDate, token } = nextProps;

    // to know what is the Bearer toke
    // -> https://stackoverflow.com/questions/25838183/what-is-the-oauth-2-0-bearer-token-exactly
    axios.get(
      `https://graph.microsoft.com/v1.0/me/calendarview?startdatetime=${startDate}&enddatetime=${endDate}&orderby=start/dateTime`,
      { headers: { Authorization: `Bearer ${token}` } },
    ).then(response => this.setState({ events: response.data.value }))
      .catch((error) => {
        console.log(error.response);
      });
  }

  render() {
    const { events } = this.state;
    if (events !== null) return events.map(event => <EventList key={event.id} event={event} />);
    return null;
  }
}

Странно то, что если я создаю console.log (токен), приложение показывает мне токен, но в то же время я получаю ошибку «GET ... 401 (Unauthorized)»

токен журнала консоли и сообщение об ошибке

Это мое приложение:

часть приложения 1

Прикладная программа часть 2

Может быть, проблема в вызове Hello.js? Я тестирую свое приложение с помощью Jest, и у меня появляется эта ошибка. Может ли это быть связано с моей проблемой?

 console.error node_modules/jest-environment-jsdom/node_modules/jsdom/lib/jsdom/virtual-console.js:29
    Error: Uncaught [TypeError: hello is not a function]

Как я могу решить?

1 Ответ

0 голосов
/ 18 января 2019

Я нашел решение!

Я должен был сделать 2-х осевой вызов:

  • один для получения токена (с POST)
  • один для использования токена в моем запросе графа Microsoft (с GET)

Мне пришлось зарегистрировать свое приложение здесь https://portal.azure.com/#home, чтобы получить идентификатор клиента и секрет.

После того, как мне нужно было отправить сообщение POST в конечную точку проверки подлинности Active Directory Azure со следующими параметрами тела:

  • grant_type : поток, который мы хотим использовать, client_credentials в моем случае.
  • client_id : идентификатор клиента (идентификатор приложения) приложения I
    создано на этапе регистрации;
  • client_secret : Секрет клиента, который я создал при регистрации шаг;
  • resource : имя ресурса, к которому я хотел бы получить доступ, https://graph.microsoft.com в этом случае.

Итак, я создал один компонент со следующим POST-запросом axios:

componentDidMount() {
    axios.post(`https://cors-anywhere.herokuapp.com/https://login.microsoftonline.com/${AZURE_ACTIVE_DIRECTORY_TENANT_NAME}/oauth2/token`,
      `grant_type=${GRANT_TYPE}&client_id=${APP_ID}&client_secret=${SECRET}&resource=${RESOURCE}`).then(res => this.setAccessToken(res.data.access_token))
      .catch((error) => {
        console.error(error.response);
      });
  }

  setAccessToken(token) {
    if (typeof token === 'string') this.setState({ accessToken: token });
  }

Примечание значение resource необходимо немного изменить, чтобы оно работало: * * Тысяча сорок-девять% 3A HTTPS% 2F% 2F% 2Fgraph.microsoft.com

Мне пришлось поставить строку 'https://cors -anywhere.herokuapp.com ' перед URL-адресом micorsoftonline, потому что в противном случае приложение сгенерировало

"заблокировано политикой CORS: в запрошенном ресурсе отсутствует заголовок 'Access-Control-Allow-Origin'." (Я не знаю почему, я все еще работаю над этим, потому что размещение этой строки не является оптимальным решением).

В компоненте EventList мне больше не нужны hellojs, поэтому я просто использую токен, сгенерированный для доступа. Мне пришлось немного изменить запрос графа Microsoft:

 componentDidMount() {
    const { accessToken } = this.props;
    const { startDate, endDate } = this.state;
    this.getEvents(startDate, endDate, accessToken);
  }

getEvents(startDate, endDate, accessToken) {
    const startDateString = startDate.toISOString();
    const endDateString = endDate.toISOString();
    axios.get(
      `https://graph.microsoft.com/v1.0/users/${USER_PUBLIC_ID}/calendarview?startdatetime=${startDateString}&enddatetime=${endDateString}&orderby=start/dateTime`,
      {
        headers: {
          Authorization: `Bearer ${accessToken}`,
        },
      },
    ).then(response => this.setEvents(response.data.value))
      .catch((error) => {
        console.error(error.response);
      });
  }

  setEvents(events) {
    const validEvent = event => typeof event.subject === 'string';
    this.setState({ events: events.filter(validEvent) });
  }

Я надеюсь, что мое решение может быть полезным и для других пользователей

...