제로초님 저번에 강좌에서 낸 숙제라고 하신 앱을 킬때마다 리프레시 토큰 갱신하는것을 구현해 보았습니다. 그런데 제가 옳은 방법으로 했는지 피드백 부탁드립니다!!
질문 1.
로그인을 해서 accesstoken과 refreshtoken을 이미 발급받았고 앱을 껐다가 다시 켰을 때를 가정했을 시
getTokenAndRefresh 함수가 실행되어 (1)의 axios.post(`${Config.API_URL}/refreshToken`,백앤드 요청이 갑니다.
AppInner.tsx
useEffect(() => {
const getTokenAndRefresh = async () => {
try {
const token = await EncryptedStorage.getItem('refreshToken');
if (!token) {
return;
}
const response = await axios.post( ////////////(1)
`${Config.API_URL}/refreshToken`,
{},
{
headers: {
authorization: `Bearer ${token}`,
},
},
);
dispatch(
userSlice.actions.setUser({
name: response.data.data.name,
email: response.data.data.email,
accessToken: response.data.data.accessToken,
}),
);
await EncryptedStorage.setItem( (3) ////////추가된 부분
'refreshToken',
response.data.data.refreshToken,
);
} catch (error) {
console.error(error);
if ((error as AxiosError).response?.data.code === 'expired') {
// refreshToken 만료되었을 때
Alert.alert('알림', '다시 로그인 해주세요.');
}
}
};
getTokenAndRefresh();
}, [dispatch]);
app.js의 백앤드에서 리프레시 토큰 유효성 검사를 한 후 (2) refreshtoken(새로 추가한 부분)와 accesstoken을 같이 발급해 줍니다. 그러면 다시 AppInner 프론트 페이지로 가서 accesstoken을 리덕스에 저장하고 refreshtoken은1은(2의) await EncryptedStorage.setItem에 저장해줍니다.
app.js (백앤드)
app.post("/refreshToken", verifyRefreshToken, (req, res, next) => {
const refreshToken = jwt.sign( // (2) 추가된 부분
{ sub: "refresh", email: res.locals.email },
jwtSecret,
{ expiresIn: "24h" }
);
const accessToken = jwt.sign(
{ sub: "access", email: res.locals.email },
jwtSecret,
{ expiresIn: "5m" }
);
if (!users[res.locals.email]) {
return res.status(404).json({ message: "가입되지 않은 회원입니다." });
}
res.json({
data: {
accessToken,
refreshToken, // 추가된 부분
email: res.locals.email,
name: users[res.locals.email].name,
},
});
});
이렇게 구현해 보았는데요. 결과는 로그인 하면 기존처럼 accesstoken과 refreshtoken이 발급되고 앱을 껐다가 키면 리프레시 토큰 유효성 검사를 한 뒤 유효하면 accesstoken과 refreshtoken을 다시 발급해주며 갱신시켜 줍니다. 만약 refreshotken이 만료되었다면 로그인 페이지로 이동하게 되구요. 시도를 해보니 잘 작동을 하는것 같은데 혹시 제가 무엇을 빼놓지는 않았는지 옳은방법으로 한것인지 제로초님의 의견이 궁금합니다!.
질문2.
강의중 제로초님은 accesstoken은 리덕스에 refreshtoken은 암호 저장소에 저장한다고 하셨는데 그러면
백엔드 db에는 둘 중 어느 토큰도 저장하지 않으시는지 궁금합니다.
만약 그렇다면 로그인 할때 백엔드에서
app.post("/login", (req, res, next) => {
const refreshToken = jwt.sign(
{ sub: "refresh", email: req.body.email },
jwtSecret,
{ expiresIn: "24h" }
);
const accessToken = jwt.sign(
{ sub: "access", email: req.body.email },
jwtSecret,
{ expiresIn: "5m" }
);
users[req.body.email].refreshToken = refreshToken; /////// 이 부분
return res.json({
data: {
name: users[req.body.email].name,
email: req.body.email,
refreshToken,
accessToken,
},
});
});
users[req.body.email].refreshToken = refreshToken;이 코드가 의미하는바가 무엇인지 궁금합니다. 디비용 더미 데이터 같은데 지웠는데도 잘 실행되더라구요. 없어도 되는 코드인가요?...