#reactjs #microsoft-graph-api
Вопрос:
Я работаю над проектом React.
Я могу войти в API graph, также могу получать контакты пользователя, но не могу получать события его календаря.
конфигурационный файл:
export const msalConfig = {
auth: {
clientId: "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
authority: "https://login.microsoftonline.com/common",
redirectUri: "http://localhost:4200",
},
cache: {
cacheLocation: "sessionStorage", // This configures where your cache will be stored
storeAuthStateInCookie: true, // Set this to "true" if you are having issues on IE11 or Edge
}
};
// Add scopes here for ID token to be used at Microsoft identity platform endpoints.
export const loginRequest = {
scopes: ["Calendars.ReadWrite", "Contacts.Read"]
};
// Add the endpoints here for Microsoft Graph API services you'd like to use.
export const graphConfig = {
graphMeEndpoint: "https://graph.microsoft.com/v1.0/me",
graphCalendarsEndpoint: "https://graph.microsoft.com/v1.0/me/events",
graphContactsEndpoint: "https://graph.microsoft.com/v1.0/me/contacts",
};
1/ Рабочая часть
файл importContact.jsx:
...
import { loginRequest, graphConfig } from '../authConfig.jsx';
import { useMsal } from "@azure/msal-react";
const ImportContacts = (props) => {
const { instance, accounts, inProgress } = useMsal();
const [accessToken, setAccessToken] = useState(null);
const [graphData, setGraphData] = useState(null);
const getMicrosoftContacts = () => {
const request = {
...loginRequest,
account: accounts[0]
};
var contacts= [];
// Silently acquires an access token which is then attached to a request for Microsoft Graph data
instance.acquireTokenSilent(request).then((response) => {
console.log('acquireTokenSilent')
setAccessToken(response.accessToken);
callMsGraph(response.accessToken).then(
response => {
setGraphData(response);
console.log(response)
for (const item of response.value){
contacts.push({
provider: 'Microsoft',
id: item.id,
email: item.emailAddresses[0].address,
firstName: item.givenName,
lastName: item.surname,
name: item.displayName,
label:item.displayName " (" item.emailAddresses[0].address ")" }
)
}
setItems(contacts);
}
);
}).catch((e) => {
instance.acquireTokenPopup(request).then((response) => {
setAccessToken(response.accessToken);
callMsGraph(response.accessToken).then(
response => {
setGraphData(response);
for (const item of response.value){
contacts.push({
provider: 'Microsoft',
id: item.id,
email: item.emailAddresses[0].address,
firstName: item.givenName,
lastName: item.surname,
name: item.displayName,
label:item.displayName }
)
}
setItems(contacts);
}
);
});
});
}
async function callMsGraph(accessToken) {
const headers = new Headers();
const bearer = `Bearer ${accessToken}`;
headers.append("Authorization", bearer);
const options = {
method: "GET",
headers: headers
};
return fetch(graphConfig.graphContactsEndpoint, options)
.then(response => response.json())
.catch(error => console.log(error));
}
...
}
2/ Нерабочая часть в файле events.jsx:
...
import { loginRequest, graphConfig } from '../authConfig.jsx';
import { useMsal } from "@azure/msal-react";
class Events extends Component {
constructor(props) {
super(props);
this.getMicrosoftEvents = this.getMicrosoftEvents.bind(this);
}
componentDidMount(){
var date = new Date();
var firstDay = new Date(date.getFullYear(), date.getMonth(), 1);
var lastDay = new Date(date.getFullYear(), date.getMonth() 1, 0);
this.getMicrosoftEvents(firstDay, lastDay);
}
getMicrosoftEvents(start, end) {
console.log('log displayed in console')
const { instance, accounts, inProgress } = useMsal();
const [accessToken, setAccessToken] = useState(null);
const [graphData, setGraphData] = useState(null);
console.log('log not displayed in console')
const request = {
...loginRequest,
account: accounts[0]
};
// Silently acquires an access token which is then attached to a request for Microsoft Graph data
instance.acquireTokenSilent(request).then((response) => {
console.log('acquireTokenSilent')
setAccessToken(response.accessToken);
callMsGraph(response.accessToken, start, end).then(
response => {
console.log('microsoft response ' response)
}
);
}).catch((e) => {
console.log('microsoft response error ' e)
instance.acquireTokenPopup(request).then((response) => {
setAccessToken(response.accessToken);
callMsGraph(response.accessToken, start, end).then(
response => {
console.log('microsoft response ' response)
}
);
});
});
async function callMsGraph(accessToken, start, end) {
console.log('callMsGraph ')
const headers = new Headers();
const bearer = `Bearer ${accessToken}`;
headers.append("Authorization", bearer);
console.log('Authorization ' bearer)
const options = {
method: "GET",
headers: headers
};
return fetch(graphConfig.graphCalendarsEndpoint
'?startDateTime='
start
'amp;endDateTime='
end,
options)
.then(response => {
console.log('microsoft response ' response.json())
response.json();
})
.catch(error => console.log(error));
}
}
Я не получаю никаких ошибок, вызов api не выполняется, разница между двумя вызовами в том, что один выполняется после нажатия кнопки, а другой при загрузке.
Добавление журналов показало мне, что проблема может быть в этой строке, так как журналы не отображаются после нее:
const { instance, accounts, inProgress } = useMsal();
Что я делаю не так?
Комментарии:
1. добавление попытки/перехвата вокруг const { экземпляр, учетные записи, InProgress } = useMsal(); выдал эту ошибку: Ошибка: Недопустимый вызов крючка. Крючки могут вызываться только внутри тела функционального компонента. Не уверен, почему он выдает эту ошибку, когда она вызывается внутри функции..
Ответ №1:
В events.jsx
событиях компонент является компонентом класса, и вы вызываете useMsal()
и useState()
подключаетесь getMicrosoftEvents
. Это не сработает, потому что крючки можно вызывать только в компонентах функций.
Вам нужно сделать компонент событий функциональным, как ImportContacts
.
Вместо
class Events extends Component {
...
Сделай это
const Events= (props) => {
const { instance, accounts, inProgress } = useMsal();
const [accessToken, setAccessToken] = useState(null);
const [graphData, setGraphData] = useState(null);
...
Комментарии:
1. Я попробую это сделать, тх