반응형
Access Token 의 문제점
- 여기서 지칭하는 Access Token은 단순히 아래 코드와 같이 jwt.sign() 을 이용해 반환받은 auth 관련 token 입니다.
const accessToken = jwt.sign(userObject, secretKey);
- Refresh Token을 사용하지 않는 Express backend는 jwt.sign()을 통해 반환받은 Access Token이 하나만 있다면 해당 token을 갖고 계속 인증이 필요한 요청을 수행할 수 있습니다.
- jwt.sign()은 실행할 때마다 다른 token을 반환하지만 기본적으로는 과거에 반환한 token은 만료가 되지 않기 때문에 보안 상 관리하기 까다롭습니다.
임시 해결법
- jwt.sign()으로 token을 발행할 때 token의 유효기간을 부여해서 만료시킬 수 있습니다.
- 여기서 발생하는 문제점들이 있는데 가장 큰 문제점은 유효기간을 길게 혹은 짧게 설정하는 것 둘 다 장단점이 확실해서 결정하기 애매하다는 것입니다.
- 유효기간을 길게 설정할 경우: token에 유효기간을 설정하는 이유가 없어집니다. 해커가 token을 탈취하면 긴 유효기간동안 계속 인증이 필요한 요청을 보낼 수 있습니다.
- 유효기간을 짧게 설정할 경우: token이 너무 빨리 만료되면 유저는 로그인을 지나치게 자주 해야될 수 있습니다.
최종 해결법: Refresh Token
- Refresh Token도 Access Token과 마찬가지로 jwt.sign()을 통해 발급 받습니다.
- Access Token의 유효기간이 끝나고 Resource Server에 인증이 필요한 요청을 보내게 되면 Invalid Token error이 발생하게 됩니다 (사진 속 E & F).
- 이 때 Access Token과 같이 발급받은 Refresh Token을 사용해 새로운 Access Token을 발급받아서 사용하게 됩니다 (G & H).
- 위 과정을 통해 유저는 새로운 token을 발급받기 위해 로그인을 다시 할 필요가 없어집니다.
- 위 과정들은 jwt package에서 자동으로 제공되는 기능들이 아닌, 직접 구현해야합니다.
- Access Token의 문제점에 대한 하나의 해결책으로 제시된 일종의 알고리즘 입니다.
- Access Token의 유효기간이 길면 생기는 보안 상 문제점들을 해결하기 위해 등장한 개념이므로 Access Token의 유효기간은 짧게, Refresh Token의 유효기간은 길게 설정합니다.
const accessToken = jwt.sign(user, secretKey, { expiresIn: "1h" });
const refreshToken = jwt.sign(user, refreshSecretKey, { expiresIn: "1d" });
res.cookie("jwt", refreshToken, {
httpOnly: true,
maxAge: 24 * 60 * 60 * 1000,
});
- 주로 Access Token은 cookie / local storage / memory에 저장하고 Refresh Token은 cookie에 저장합니다.
- 위의 res.cookie()를 사용해서 refreshToken을 저장하는 코드를 보면 httpOnly: true로 설정해준 것을 볼 수 있습니다.
- httpOnly: true로 설정해준 cookie는 XSS Cross Site Scripting 공격을 예방할 수 있습니다.
- XSS Cross Site Scripting 공격은 쉽게 말해서, 인증이 필요한 요청을 토큰 등을 탈취해서 악의적인 코드를 삽입하는 공격입니다.
- 다시 말해, javascript를 통해 해당 쿠키에 접근할 수 없게 설정하는 것입니다 (탈취, 조작 예방).
- 또한, maxAge를 통해 cookie의 유효기간을 설정해줍니다.
천재는 누구보다도 고통을 참아내는 능력이 뛰어난 자를 일컫는다.
- 토마스 칼라일 -
반응형
'개발' 카테고리의 다른 글
BE (2) - PUT vs. PATCH (0) | 2024.01.25 |
---|---|
BE (1) - res.json() vs. res.send() vs. res.end() (0) | 2024.01.24 |