작성
·
336
0
const errorLink = onError(({ graphQLErrors, operation, forward }) => {
//1. 에러 캐치
if (typeof graphQLErrors !== "undefined") {
for (const err of graphQLErrors) {
//1-2. 해당 에러가 토큰만료 에러인지 체크
if (err.extensions.code === "UNAUTHENTICATED") {
return fromPromise(
//2. refreshtoken으로 accessToken을 재발급 받기
getAccessToken().then((newAccessToken) => {
setAccessToken(newAccessToken ?? "");
//3. 재발급 받은 accesstoken 으로 방금 실패한 쿼리 실행하기
operation.setContext({
header: {
...operation.getContext().headers, //기존의 authorization: Bearer '만료된 토큰'
Authorization: `Bearer ${newAccessToken}`, //3-2 authorization 만 바꿔치기
},
});
})
).flatMap(() => forward(operation)); //3-3 방금 수정한 쿼리 재요청하기
}
}
}
});
수업이랑 동일하게 코드를 작성하였으나 버튼을 눌러도 재발급된 accessToken 이 들어가지 않아 error 가 발생하고 2번이상 눌러야지만 accesstoken 이 제대로 수정되서 정상적으로 실행됩니다. 어디가 문제일까요?
답변 3
0
export const getAccessToken = async (): Promise<string | undefined> => {
try {
const graphQlClient = new GraphQLClient(
"https://backend-practice.codebootcamp.co.kr/graphql",
{ credentials: "include" } // cookie 에 data를 저장하기 위한 설정
);
const result = await graphQlClient.request<
Pick<IMutation, "restoreAccessToken">
>(RESTORE_ACCESS_TOKEN);
const newAccessToken = result?.restoreAccessToken.accessToken;
console.log(newAccessToken);
return newAccessToken;
} catch (error) {
if (error instanceof Error) {
console.log(error.message);
}
}
};
getAccessToken 도 제대로 작성된거 같은데 윗방식대로 작성해야 되는걸까요?
0
안녕하세요! kyb1208tg님!
위 코드를 보면, 수업의 내용과 크게 다른 것이 없이 잘 작성하신 것 같아요!
따라서, getAccessToken() 파트의 코드를 한 번 점검해 보실 필요가 있을 것 같아요!
0
안녕하세요, 인프런 AI 인턴이에요.
버튼을 눌러도 재발급된 accessToken이 바로 적용되지 않는 문제가 발생하는군요. 이 문제의 원인은 아마 비동기적으로 실행되는 코드 때문일 것으로 추측됩니다. getAccessToken()
함수는 비동기로 동작하며, 그 결과값이 반환되기 전에 다음 코드가 실행되기 때문에 accessToken이 바로 적용되지 않는 것입니다. 이 때문에 에러가 발생하고, 2번 이상의 버튼 클릭이 필요한 것 같습니다.
해결 방법으로는 getAccessToken().then()
메소드 블록 내에서 operation.setContext()
를 호출하고, forward(operation)
을 반환하는 대신 forward(operation).flatMap(() => ...)
을 사용하여 프로미스 체인을 연결해 보세요. 이렇게 하면 getAccessToken()
함수의 결과가 반영된 후에만 다음 코드가 실행됩니다.
다음은 수정된 코드입니다:
const errorLink = onError(({ graphQLErrors, operation, forward }) => {
if (typeof graphQLErrors !== "undefined") {
for (const err of graphQLErrors) {
if (err.extensions.code === "UNAUTHENTICATED") {
return fromPromise(
getAccessToken().then((newAccessToken) => {
setAccessToken(newAccessToken ?? "");
operation.setContext({
header: {
...operation.getContext().headers,
Authorization: `Bearer ${newAccessToken}`,
},
});
return forward(operation).flatMap((response) => {
if (response.errors) {
throw new Error("GraphQL Error");
}
return response;
});
})
);
}
}
}
});
위의 코드를 사용하여 한 번 시도해 보시고, 문제가 해결되었는지 확인해 주세요. 추가 도움이 필요하시면 언제든지 말씀해 주세요. 감사합니다.