따로 분리한 getAccessToken() 함수 result의 타입
강의를 보고 똑같이 따라했지만 저는 result에 타입이 unknown이라고 뜨네요.
이때문인지는 모르겠지만 로그인 후 넘어간 페이지에서 버튼 누르는 과정에서 오류가 뜹니다.ㅜ

아래는 아폴로 세팅입니다. 문제가 무엇일까요?
import {
ApolloClient,
ApolloLink,
ApolloProvider,
fromPromise,
InMemoryCache,
} from "@apollo/client";
import { onError } from "@apollo/client/link/error";
import { createUploadLink } from "apollo-upload-client";
import { useEffect } from "react";
import { useRecoilState } from "recoil";
import { getAccessToken } from "../../../commons/libraries/getAccessToken";
import { accessTokenState } from "../../../commons/store";
const GLOBAL_STATE = new InMemoryCache();
interface IApolloSettingProps {
children: JSX.Element;
}
export default function ApolloSetting(props: IApolloSettingProps) {
const [accessToken, setAccessToken] = useRecoilState(accessTokenState);
// 3. 프리랜더링 무시 - useEffect
useEffect(() => {
console.log("지금은 브라우저다");
const result = localStorage.getItem("accessToken");
console.log(result);
if (result) setAccessToken(result);
}, []);
// 에러를 캐치하고 캐치한 에러가 토큰만료면 재발급 받은 후, 기존의 쿼리를 포워드해서 다시 날려준다.
const errorLink = onError(({ graphQLErrors, operation, forward }) => {
// 1-1. 에러를 캐치
if (graphQLErrors) {
for (const err of graphQLErrors) {
// 1-2. 해당 에러가 토큰만료 에러인지 체크(UNAUTHENTICATED)
if (err.extensions.code === "UNAUTHENTICATED") {
return fromPromise(
// 2-1. refreshToken으로 accessToken을 재발급
getAccessToken().then((newAccessToken) => {
// 2-2. 재발급 받은 accessToken 저장하기
setAccessToken(newAccessToken);
// 3-1. 재발급 받은 accessToken으로 방금 실패한 쿼리의 정보 수정하기
if (typeof newAccessToken !== "string") return;
operation.setContext({
headers: {
...operation.getContext().headers, // 만료된 토큰이 추가되어 있는 상태
Authorization: `Bearer ${newAccessToken}`, // 토큰만 새것으로 바꿔치기
},
});
})
).flatMap(() => forward(operation)); // 3-2. 방금 수정한 쿼리 재요청하기
}
}
}
});
const uploadLink = createUploadLink({
uri: "https://backendonline.codebootcamp.co.kr/graphql", // https 로 변경(토큰 정보를 쿠키에 담을 수 있게)
headers: { Authorization: `Bearer ${accessToken}` },
credentials: "include", // https 변경으로 추가된 조건
});
const client = new ApolloClient({
link: ApolloLink.from([errorLink, uploadLink as unknown as ApolloLink]),
// cache: new InMemoryCache(),
cache: GLOBAL_STATE,
});
// prettier-ignore
// 주석으로 prettier-ignore 해주면 한줄로 바뀌는걸 막아준다
return <ApolloProvider client={client}>
{props.children}
</ApolloProvider>;
}혹시 이부분때문일까요??
link: ApolloLink.from([errorLink, uploadLink as unknown as ApolloLink])
답변 1
0
안녕하세요!
해당 오류는 백엔드 서버에서 refreshToken이 새로운 토큰을 재발급해주는 로직이 잘못되어 토큰바꿔치기가 안되어 발생하는 오류입니다.
따라서 해당 부분을 보완한 서버로 바꿔주셔야 합니다.
uploadLink와 getAccessToken() 부분에 주소를 아래 주소로 바꿔주세요!
https://backend-practice.codebootcamp.co.kr/graphql
감사합니다.😁
0
감사합니다!! 수정하니까 되네요!!
그런데 또 궁금한점이 있습니다.
수업노트에 보면 아래처럼 예시를 보여주시는데,
// src/apollo/index.tsx 파일
export default function ApolloSetting(props: IApolloSettingProps) {
const [accessToken, setAccessToken] = useRecoilState(accessTokenState);
const [userInfo, setUserInfo] = useRecoilState(userInfoState);
if (!accessToken || !userInfo) return;
setUserInfo(JSON.parse(userInfo));
}, []);
const errorLink = onError(({ graphQLErrors, operation, forward })=>{
// 1-1. 에러를 캐치
// 1-2. 해당에러가 토큰만료 에러인지 체크(UNAUTHENTICATED)
// 2-1. refreshToken으로 accessToken을 재발급 받기
// 2-2. 재발급 받은 accessToken 저장하기
// 3-1. 재발급 받은 accessToken으로 방금 실패한 쿼리정보 수정하기
// 3-2. 재발급 받은 accessToken으로 방금 수정한 쿼리 재요청하기
})
const uploadLink = createUploadLink({
uri: "http://backendonline.codebootcamp.co.kr/graphql",
headers: { Authorization: `Bearer ${accessToken}` },
credentials: "include",
});
const client = new ApolloClient({
link: ApolloLink.from([uploadLink]),
cache: APOLLO_CACHE,
connectToDevTools: true,
});
return (
<ApolloProvider client={client}>
{props.children}
</ApolloProvider>
)
}
아래 두 부분은 수업에서 진행하지 않았던 것 같은데
userInfo 글로벌스테이트에 저장하는 부분
client 설정에 connectToDevTools 부분
혹시 어떻게 추가가 된건지 알 수 있을까요?
const [userInfo, setUserInfo] = useRecoilState(userInfoState); const client = new ApolloClient({
link: ApolloLink.from([uploadLink]),
cache: APOLLO_CACHE,
connectToDevTools: true,
});
fetchBoardsOfMine, fetchBoardsCountOfMine 에러 문의드립니다
0
41
1
댓글 기능 구현 중 질문드립니다.
0
67
1
쿠폰코드 발급
0
147
2
example 서버 플레이그라운드, API 접속 모두 안됩니다.
0
89
2
문의드립니다!! ㅠㅠ
0
107
2
graphql 백엔드 서버가 포폴용 빼곤 접속이 안됩니다.
0
80
2
_app.js 작성 이후로 에러가 발생하네요
0
96
2
학습자료
0
72
2
학습자료가 안열립니다.
0
51
2
플레이 그라운드 퀴즈 문제 질문이 있습니다.
0
61
0
기존강의 구매자, 업데이트 끝인가요?
0
111
3
업데이트 버전 수강
0
89
2
완벽한 프론트엔드
0
136
2
나만의 쇼핑몰 샘플 페이지 접속 확인부탁드립니다.
0
84
1
graphql 접속이 안됩니다.
0
101
2
const, let 사용 질문 드립니다.
0
72
2
싸이월드 만들기 1탄 피드백 부탁드립니다.
0
123
2
회원가입 과제 피드백 부탁드립니다.
0
81
2
styled.span / styled.input "CSS 자동완성"
0
47
1
쿠폰 발급 관련
0
167
2
서버 502 error
0
247
2
쿠폰 다시 부탁드려도 될가여?
0
140
2
a태그 패딩했을때 왜 크기가 줄어들지 않고 늘어나나요
0
185
2
2분 44초 질문
0
132
3





