React를 사용하여 Fullcalendar에서 Google 캘린더 이벤트 표시
27992 단어 reactjavascript
Google Identity Services은 Google에서 시행하는 새로운 인증 흐름이 되어 새로 생성된 자격 증명이 대체to Google Sign-In Platform를 허용하지 않고 기본적으로 이를 사용하도록 합니다.
이전 방법을 사용하여 React 애플리케이션을 Google 캘린더에 연결하는 방법에 대한 몇 가지 자습서가 있지만 구현해야 하는 특정 흐름에 대한 자습서를 거의 찾을 수 없었기 때문에 직접 작성하기로 결정했습니다.
기사를 간략하게 유지하기 위해 여기에서는 자격 증명을 생성하고 OAuth 화면을 구성하는 방법을 설명하지 않을 것이며 이를 수행하는 방법에 대한 많은 문서가 있습니다.
사용자 흐름에 대한 몇 가지 세부 정보:
Google에 로그인
@react-oauth/google'
라이브러리를 사용하여 인증 흐름, ux_mode 및 인증 토큰을 얻기 위한 범위를 구성한 다음 Google에 API 호출을 위한 인증 토큰을 요청하는 데 사용할 인증 토큰을 얻습니다.
모든 것은 간단한 버튼으로 시작됩니다.
<GoogleButton
id='google-calendar-connection'
label='Connect Google Calendar'
onClick={googleLogin}
/>
googleLogin 함수는 OAuth 화면을 열고 승인 토큰을 전달하는 백엔드를 호출하여 액세스 토큰을 얻습니다.
const getGoogleAccessToken = async (authorizationCode) => {
const response = await axios.post(
`/api/google/accesstoken`,
{ authorizationCode }
);
if (response.data.access_token) {
localStorage.setItem("google_access_token", JSON.stringify(response.data.access_token));
}
if (response.data.expiry_date) {
localStorage.setItem("google_access_token_expiry_date", JSON.stringify(response.data.expiry_date));
}
return response.data;
}
const fetchGoogleAccessToken = async (tokenResponse) => {
const accessToken = await getGoogleAccessToken(tokenResponse.code);
if (localStorage.getItem("google_access_token")) {
setGoogleCalendarSync(true);
}
return accessToken;
}
const googleLogin = useGoogleLogin({
onSuccess: fetchGoogleAccessToken,
onError: error => console.log(error),
flow: 'auth-code',
ux_mode: 'popup',
scope: GOOGLE_CALENDAR_SCOPES
});
getGoogleAccessToken()
함수 호출을 처리하는 API 엔드포인트:
const getAccessToken = async (req, res) => {
const { authorizationCode } = req.body;
const user = req.user;
// Get access and refresh tokens (if access_type is offline)
let { tokens } = await oauth2Client.getToken(authorizationCode);
oauth2Client.setCredentials(tokens);
let userGoogleAuthentication;
userGoogleAuthentication = await user.getGoogleAuthentication();
//If the user has already a google authentication, update the refresh token,
//otherwise create a google authentication object and associate it to the user.
if (userGoogleAuthentication) {
await userGoogleAuthentication.update({ refresh_token: tokens.refresh_token });
}
else {
userGoogleAuthentication =
await GoogleAuthentication.create({
refresh_token: tokens.refresh_token,
userId: user.id
});
}
return res.status(200).json({ ...tokens });
}
이제 브라우저의 localStorage에 액세스 및 갱신 토큰이 각각 google_access_token 및 google_access_token_expiry_date로 있습니다. 남은 것은 events
의 FullCalendar
속성에 대한 이벤트를 가져오는 기능의 일부로 Google 캘린더 이벤트를 가져오는 것입니다. 이 비트에는 현재 토큰이 만료된 경우 백엔드에서 토큰을 새로 고치는 기능이 포함되어 있습니다.
다음은 프런트엔드 부분입니다.
const refreshGoogleAccessToken = async () => {
const response = await axios.post(
`/api/google/refreshtoken`,
{}
);
if (response.data.access_token) {
localStorage.setItem("google_access_token", JSON.stringify(response.data.access_token));
}
if (response.data.expiry_date) {
localStorage.setItem("google_access_token_expiry_date", JSON.stringify(response.data.expiry_date));
}
return response.data;
}
//API call to the Google Calendar endpoint.
const googleEventsFetch = async ({ token, from, until }) => {
const response = await fetch(
`${GOOGLE_CALENDAR_EVENTS_API_URL}/?key=${GOOGLE_CALENDAR_API_KEY}&orderBy=startTime&singleEvents=true&timeMin=${from.toISOString()}&timeMax=${until.toISOString()}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
return response;
}
//Small wrapper around functionality
const getGoogleEvents = async ({ token, from, until }) => {
if (from && until) {
const response = await googleEventsFetch({ token, from, until });
if (response.status === OK) {
const data = await response.json();
return {
status: response.status,
items: data.items
}
}
else {
return {
status: response.status,
items: []
}
}
}
else return [];
}
// Load events from Google Calendar between 2 dates.
const loadGoogleCalendarEvents = useCallback(async (from, until) => {
const googleAccessToken = localStorage.getItem("google_access_token");
const googleAccessTokenExpirationDate = localStorage.getItem("google_access_token_expiry_date");
//If the's an expiration date in the offline storage.
if (googleAccessTokenExpirationDate && googleAccessToken) {
const googleAccesTokenExpirationDateParsed = parseInt(googleAccessTokenExpirationDate);
const gAccesTokenExpDateMoment = moment(googleAccesTokenExpirationDateParsed);
const currentDateMoment = moment();
//If the token has expired.
if (currentDateMoment.isAfter(gAccesTokenExpDateMoment)) {
localStorage.removeItem("google_access_token_expiry_date");
localStorage.removeItem("google_access_token");
//Get a new access token & expiry_date with the refresh token.
const { access_token: newAccessToken} = await refreshGoogleAccessToken();
if (newAccessToken) {
const newResponse = await getGoogleEvents({
token: newAccessToken,
from,
until
});
if (newResponse.status === OK) {
setGoogleCalendarSync(true);
return newResponse.items;
}
else {
setGoogleCalendarSync(false);
return [];
}
}
}
// If the token hasn't expired yet.
else {
const response = await getGoogleEvents({
token: googleAccessToken,
from,
until
});
if (response.status === OK) {
return response.items;
}
else { //Token expired
setGoogleCalendarSync(false);
}
}
}
else {
return [];
}
}, []);
const fetchEvents = async (fetchInfo, successCallback) => {
const googleEvents = await loadGoogleCalendarEvents(fetchInfo.start, fetchInfo.end);
//...Merging googleEvents with local events..
}
<FullCalendar
...attributes...
events={fetchEvents} // alternatively, use the `events` setting to fetch from a feed
/>
마지막으로 API 끝점은 새로 고침 토큰을 요청합니다. 새로 고침 토큰은 각 사용자별로 DB에 저장됩니다.
const refreshToken = async (req, res) => {
const user = req.user;
const userGoogleAuthentication = await user.getGoogleAuthentication();
if (userGoogleAuthentication) {
const tokenResponse = await oauth2Client.refreshToken(userGoogleAuthentication.refresh_token);
return res.status(200).json({ ...tokenResponse.tokens });
}
else {
return res.sendStatus(500);
}
}
그게 다야, 다른 사람에게 도움이 되길 바랍니다.
재미있게 보내세요!
퍼머링크: https://www.estebansastre.com/google-calendar-events-fullcalendar-react/
Reference
이 문제에 관하여(React를 사용하여 Fullcalendar에서 Google 캘린더 이벤트 표시), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다
https://dev.to/fr0gs/show-google-calendar-events-in-fullcalendar-with-react-fld
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)
<GoogleButton
id='google-calendar-connection'
label='Connect Google Calendar'
onClick={googleLogin}
/>
const getGoogleAccessToken = async (authorizationCode) => {
const response = await axios.post(
`/api/google/accesstoken`,
{ authorizationCode }
);
if (response.data.access_token) {
localStorage.setItem("google_access_token", JSON.stringify(response.data.access_token));
}
if (response.data.expiry_date) {
localStorage.setItem("google_access_token_expiry_date", JSON.stringify(response.data.expiry_date));
}
return response.data;
}
const fetchGoogleAccessToken = async (tokenResponse) => {
const accessToken = await getGoogleAccessToken(tokenResponse.code);
if (localStorage.getItem("google_access_token")) {
setGoogleCalendarSync(true);
}
return accessToken;
}
const googleLogin = useGoogleLogin({
onSuccess: fetchGoogleAccessToken,
onError: error => console.log(error),
flow: 'auth-code',
ux_mode: 'popup',
scope: GOOGLE_CALENDAR_SCOPES
});
const getAccessToken = async (req, res) => {
const { authorizationCode } = req.body;
const user = req.user;
// Get access and refresh tokens (if access_type is offline)
let { tokens } = await oauth2Client.getToken(authorizationCode);
oauth2Client.setCredentials(tokens);
let userGoogleAuthentication;
userGoogleAuthentication = await user.getGoogleAuthentication();
//If the user has already a google authentication, update the refresh token,
//otherwise create a google authentication object and associate it to the user.
if (userGoogleAuthentication) {
await userGoogleAuthentication.update({ refresh_token: tokens.refresh_token });
}
else {
userGoogleAuthentication =
await GoogleAuthentication.create({
refresh_token: tokens.refresh_token,
userId: user.id
});
}
return res.status(200).json({ ...tokens });
}
const refreshGoogleAccessToken = async () => {
const response = await axios.post(
`/api/google/refreshtoken`,
{}
);
if (response.data.access_token) {
localStorage.setItem("google_access_token", JSON.stringify(response.data.access_token));
}
if (response.data.expiry_date) {
localStorage.setItem("google_access_token_expiry_date", JSON.stringify(response.data.expiry_date));
}
return response.data;
}
//API call to the Google Calendar endpoint.
const googleEventsFetch = async ({ token, from, until }) => {
const response = await fetch(
`${GOOGLE_CALENDAR_EVENTS_API_URL}/?key=${GOOGLE_CALENDAR_API_KEY}&orderBy=startTime&singleEvents=true&timeMin=${from.toISOString()}&timeMax=${until.toISOString()}`,
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);
return response;
}
//Small wrapper around functionality
const getGoogleEvents = async ({ token, from, until }) => {
if (from && until) {
const response = await googleEventsFetch({ token, from, until });
if (response.status === OK) {
const data = await response.json();
return {
status: response.status,
items: data.items
}
}
else {
return {
status: response.status,
items: []
}
}
}
else return [];
}
// Load events from Google Calendar between 2 dates.
const loadGoogleCalendarEvents = useCallback(async (from, until) => {
const googleAccessToken = localStorage.getItem("google_access_token");
const googleAccessTokenExpirationDate = localStorage.getItem("google_access_token_expiry_date");
//If the's an expiration date in the offline storage.
if (googleAccessTokenExpirationDate && googleAccessToken) {
const googleAccesTokenExpirationDateParsed = parseInt(googleAccessTokenExpirationDate);
const gAccesTokenExpDateMoment = moment(googleAccesTokenExpirationDateParsed);
const currentDateMoment = moment();
//If the token has expired.
if (currentDateMoment.isAfter(gAccesTokenExpDateMoment)) {
localStorage.removeItem("google_access_token_expiry_date");
localStorage.removeItem("google_access_token");
//Get a new access token & expiry_date with the refresh token.
const { access_token: newAccessToken} = await refreshGoogleAccessToken();
if (newAccessToken) {
const newResponse = await getGoogleEvents({
token: newAccessToken,
from,
until
});
if (newResponse.status === OK) {
setGoogleCalendarSync(true);
return newResponse.items;
}
else {
setGoogleCalendarSync(false);
return [];
}
}
}
// If the token hasn't expired yet.
else {
const response = await getGoogleEvents({
token: googleAccessToken,
from,
until
});
if (response.status === OK) {
return response.items;
}
else { //Token expired
setGoogleCalendarSync(false);
}
}
}
else {
return [];
}
}, []);
const fetchEvents = async (fetchInfo, successCallback) => {
const googleEvents = await loadGoogleCalendarEvents(fetchInfo.start, fetchInfo.end);
//...Merging googleEvents with local events..
}
<FullCalendar
...attributes...
events={fetchEvents} // alternatively, use the `events` setting to fetch from a feed
/>
const refreshToken = async (req, res) => {
const user = req.user;
const userGoogleAuthentication = await user.getGoogleAuthentication();
if (userGoogleAuthentication) {
const tokenResponse = await oauth2Client.refreshToken(userGoogleAuthentication.refresh_token);
return res.status(200).json({ ...tokenResponse.tokens });
}
else {
return res.sendStatus(500);
}
}
Reference
이 문제에 관하여(React를 사용하여 Fullcalendar에서 Google 캘린더 이벤트 표시), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/fr0gs/show-google-calendar-events-in-fullcalendar-with-react-fld텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)