Реагировать на данные календаря Microsoft Outlook без сеанса входа в систему с помощью Hello.js
Я создаю календарь React, который берет данные из "Календаря Microsoft Outlook", используя клиентский JavaScript SDK "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://stackru.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)"
токен журнала консоли и сообщение об ошибке
Это мое приложение уместно:
Принадлежность приложения, часть 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 ответ
Я нашел решение!
Я должен был сделать 2 вызова Axios:
- один для получения токена (с POST)
- один для использования токена в моем запросе графа Microsoft (с GET)
Мне пришлось зарегистрировать свое приложение здесь https://portal.azure.com/, чтобы получить идентификатор клиента и секрет.
После этого мне нужно было отправить сообщение POST в конечную точку проверки подлинности Active Directory Azure со следующими параметрами тела:
- grant_type: поток, который мы хотим использовать, client_credentials в моем случае.
- client_id: идентификатор клиента (идентификатор приложения) приложения I
созданный на этапе регистрации; - client_secret: секрет клиента, который я создал на этапе регистрации;
- ресурс: имя ресурса, к которому я хотел бы получить доступ, в данном случае https://graph.microsoft.com/.
Итак, я создал один компонент со следующим аксиальным POST-запросом:
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 });
}
ПРИМЕЧАНИЕ. Значение ресурса необходимо немного изменить, чтобы оно работало: https% 3A% 2F% 2Fgraph.microsoft.com% 2F
Мне пришлось поместить строку " 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) });
}
Я надеюсь, что мое решение может быть полезным и для других пользователей