storage로 관리하던 token, cookie로 넘기자
refresh는 해결되었지만 큰 문제가 하나 더 남았었습니다.
바로 token인데요.
token을 cookie에 싣는 방법으로 빠르게 개발을 진행하기 위해
제가 발표에 사용했던 자료를 포스팅하고자 합니다.
1. 문제점과 해결 방안 제시
그동안 서비스에서 로그인 시, 서버로부터 받아온 response의
token(= refresh, access)을 localstorage에 보관해왔습니다.
해당 방식의 문제점은 크래커가 localStorage에 접근하는 코드 한 줄로
token에 쉽게 접근이 가능하다는 점인데요.(XSS Attack)
token 조작으로 타 유저의 이미지 변경, 원치 않는 정보 변경 등이 이뤄질 수 있으므로
이에 대한 대응이 필요한데 여러 대응책 중 하나가 바로 Cookie를 활용하는 것입니다.
2. 왜 Cookie를 활용해야 하는가
장점)
XSS Attack으로부터 안전하다.
cookie의 HTTP ONLY 옵션을 사용하여 JS로 쿠키에 접근할 수 없도록 처리 가능합니다.
그렇기에 XSS Attack으로 쿠키에 담긴 token 정보를 탈취할 수 없습니다.
(HTTP ONLY 옵션은 서버에서 설정이 가능합니다.)
단점)
따로 설정하지 않아도 HTTP Request에 담아서 보내지는 것이 cookie이기에
크래커가 Request URL을 알고있다면 유저 Request를 조작하기 쉬운데요,
이를 방지할 수 있는 cookie의 속성이 존재합니다.
localStorage의 장점을 쿠키에서도 적용 가능하다는 의미인데요.
same-site 속성 설정과 JS의 fetch API 속성 기본값 등으로
Reequest에 쿠키를 싣지 않을 수 있게 되었습니다.
Cookie를 왜 사용해야 하는지에 대한 설명을 했으니
어떻게 적용해야 할 지에 대해서도 말해야겠죠?
아래에 이어서 말씀드리겠습니다.
3. 적용 방법
1) 서버 response 변경
: 로그인 요청에 대한 응답을 변경.
현재는 이들 토큰을 응답 본문에 포함시키고 있는데,
이를 HTTP-only 쿠키로 전달하도록 변경해야 합니다.
쿠키를 설정할 때 'httpOnly' 속성을 true로 설정하여 자바스크립트에서
쿠키에 접근하지 못하도록 해야 합니다.
클라이언트에서는 더 이상 응답 본문에서 token을 읽지 않아도 됩니다.
대신, 브라우저가 자동으로 요청에 쿠키를 포함시킬 것입니다.
따라서 클라이언트는 단순히 서버로부터 응답을 받고, 필요에 따라 새로운 요청을 보내면 됩니다.
2) Token 갱신 처리
: access token이 만료되면, 클라이언트는 refresh token을 사용하여 새로운 access token을 얻습니다.
이때 서버는 refresh token이 포함된 쿠키를 받게 됩니다.
서버는 이 refresh token을 확인하고, 유효하다면 새로운 access token을 생성하여
HTTP-only 쿠키로 클라이언트에게 전달합니다.
이 방식을 사용하면, 클라이언트와 서버 모두에서 Token을 안전하게 관리할 수 있습니다.
또한, 클라이언트는 Token의 상세 내용을 알 필요 없이, 단지 서버가 제공하는 Token을 사용하면 됩니다.
그리고 사용자는 재로그인 없이 계속해서 서비스를 이용할 수 있습니다.
4. 또 다른 적용 방법
Refresh Token 하나만 사용하는 건데요.
프론트에서 refresh token으로만 요청을 하고, 나머지를 백엔드에서 처리해주는 방식으로
이전 직장 동료분께 공유받은 방법이 있습니다.
프론트에서는 쿠키를 저장소에 두진 않고 서버에서 response로 전달될 때
set-cookie로 전달되어서 사용하는 방식이라고 하시네요!
해당 방법을 사용한다면 서버와 클라이언트 둘 다 작업이 필요하지만
보안과 코드 효율성을 따졌을 땐 좋아보이는 방법으로 보여집니다.
5. 선택
발표 이후 Refresh Token은 Cookie로, Access Token은 로그인의 response로 전달받아
localStorage에서 관리하기로 결정했습니다.
하지만 언제까지고 localStorage에 저장하진 않을거에요.
어딘가에 캐싱을 해둬야겠죠?