일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
- 부족한 금액 계산하기
- s3확장자
- 프로그래머스
- vscode
- interactive_timeout
- express
- 커밋 한번에
- 리액트코드정렬
- next #middleware
- EC2
- react
- max_allowed_packet
- Node
- useReducer
- prettier
- MySQL
- AWS
- reacts3
- utf8mb4
- axios
- elasticIP
- dotenv
- 자연수 뒤집어 배열로 만들기
- 프리티어
- 코딩테스트
- 코드정렬
- 자동완성방지
- 제일 작은 수 제거하기
- 리액트
- .env
- Today
- Total
Sungtt
랭킹페이지 새로고침 시 내 순위가 안나오는 오류 본문
개요
랭킹페이지는 useEffect를 통해 서버에 데이터를 받아와 랭킹을 출력해준다.
자신의 순위를 보여주는 api는 스토어의 userId를 인자로 담아 그 값을 조회해서 출력해준다.
다른 페이지에서 렌더링 후 진입한다면 스토어에 값이 할당 되어있어 문제없이 출력되지만
랭킹 페이지에서 새로고침 시 userId 스토어값에 값이 undifined라서 api요청을 해서 랭킹이 안나오는 오류를 만났다.
해결 과정
먼저 req객체의 id변수를 사용하고자했다.
하지만 새로고침시에는 req객체에 아무값이 들어있지않았다.
이 원인을 생각해보았다.
원인은
서버에서는 api요청마다 jwt검증을 진행하고 jwt엔 유저의 id가 들어있다.
이를 req.decoded.userId 변수에 할당하여 여기저기 사용중이다.
하지만 늘 첫 검증시에는 토큰이 없다는 오류를 만나고있었다.
현재 새로고침 시 로그인 정보를 유지하는 방법의 전개다.(이 방법은 오류가 나고있는 방법)
1. 브라우저 새로 고침
2. DOM이 parsing될 때 로컬스토리지의 토큰을 획득
3. 토큰을 axios.post에 담아 login/localstorage에 api 요청
4. 모든 api요청은 서버 미들웨어를 통해 헤더에 들어있는 토큰을 검증 한다.(처음엔 헤더에 값이 없기때문에 오류)
5. 헤더토큰이 정상이라면 복호화된 값을 express request 변수에 추가
5-1. 헤더토큰이 없다면 바로 next()
6. login/localstorage api가 post로 들어온 토큰을 검증을 try한다
6-1. 토큰이 정상이면 토큰에 들어있는 id로 DB의 userInfo를 획득하고 토큰과 userInfo, id를 응답해준다.
6-2. 토큰이 비정상이면 위 값을 모두 undifined로 응답해준다.
7. 클라이언트는 login/localsotrage의 응답을 받아와 token값은 axios headers에 설정한다.
8. 응답받은 userInfo와 id는 스토어에 저장하여 프론트에 출력한다.
이때 브라우저 첫 렌더링때는 위 과정을 한번 거치기전에는
헤더에 아무값도 들어있지않기때문에 무조건 오류가 난다.
이때 토큰 검증을 못했으니 당연히 req변수들도 할당되어있지않는 상태다.
해결하려면 첫 api요청에 토큰검증에 바로 성공해야 랭킹페이지에서도 req변수를 참조하여 값을 조회할 수 있다.
두가지 방법을 생각했다.
첫번째
2번 과정에서 토큰을 획득하면서 axios headers를 설정한 뒤 api요청을 하는 것.
이러면 토큰의 유효성을 바로 검사할 수 있고,
토큰이 유효하다면 위 사이클을 한번 돌기전에도 서버에서 즉각적으로 정상적인 req변수 참조가 가능하다.
function loadUser() {
try {
let user: string | null = localStorage.getItem('token');
if (!user) return;
axios.defaults.headers.common['Authorization'] = user;
store.dispatch(login_localstorage(user));
} catch (e) {
console.log(e);
}
}
loadUser();
두번째
서버 미들웨어가 헤더에 토큰과 post에 들어온 토큰도 체크하는 것
이 방법도 작동은 하지만 코드도 보기싫어지고 기존보다 더 많은 비용이 든다.(물론 미미할것임..)
const jwtCheck = (req: Request, res: Response, next: NextFunction) => {
let token: string | undefined = req.headers.authorization as string;
console.log('바디에 들어있는 값');
if (req.body.token) {
try {
req.decoded = checkToken(req.body.token.token);
req.isToken = true;
console.log('유효한 토큰');
next();
} catch (e) {
console.log('만료된 토큰');
req.isToken = false;
next();
}
} else if (token) {
try {
req.decoded = checkToken(token);
req.isToken = true;
console.log('유효한 토큰');
next();
} catch (e) {
console.log('만료된 토큰');
req.isToken = false;
next();
}
}
결론
첫번째 방법을 통해 해결하였다.
이제 랭킹페이지에서 새로고침하여도 userId값을 서버에서 바로 조회할 수 있게되었다.
요청 시 userId값을 넘겨줄 필요도 없게되었다.
물론 이는 다른 페이지의 userId를 인자로 담아 요청하는 모든 api에 해당된다.
'프로젝트 > 개인 프로젝트 [공책게임]' 카테고리의 다른 글
aws 배포과정 (0) | 2022.09.19 |
---|---|
던전을 올라가는 목적성을.. (0) | 2022.08.21 |
랭킹 페이지네이션 UI 짧은 고찰.. (0) | 2022.08.18 |
페이지네이션 뇌피셜 (0) | 2022.08.17 |
리워드지급 switch문 탈출기 (0) | 2022.08.02 |