JWT 기반 인증 로그인 구현하기 - (2)

yunbiyomi·2024년 1월 4일



📌 JWT


🔷 기본 구조

.을 구분자로 3개의 문자열로 나눠진다.

  • header : 토큰의 타입을 지정하는 typ해싱 알고리즘을 지정하는 alg로 이루어짐.
    보통 해시 알고리즘으로 HMAC SHA256 도는 RSA가 사용됨.

  • payload : 토큰에 담을 정보가 들어있음. 정보의 한조각을 claim(클레임)이라고 부르고, 클레임은 namevalue의 한 쌍으로 이루어져 있음.

  • signature : 헤더의 인코딩값정보의 인코딩 값 을 합친 후 주어진 비밀키로 해쉬를 하여 생성



🌐 https://jwt.io/
위의 사이트를 통해 브라우저상에서 JWT 토큰검증하고 생성 할 수 있다.

예시로 만들어본 토큰이다.

해석해보면,
header -> 토큰의 타입은 JWT, 해싱 알고리즘으로 HMAC SHA256이 사용됨
payload -> emailusername 두개의 비공개 클레임과 1개의 등록된 클레임으로 이루어짐
등록된 클레임인 exp는 토큰의 만료시간으로 시간이 NumericDate 형식으로 되어있음
signature -> 비밀키의 값으로 secret-code-is-secret를 사용함

왼쪽 밑에 Signature Verified라 뜨기 때문에 JWT 토큰이 검증되었음을 알 수 있다.





🔷 인증 절차

본격적으로 코드 작성 전 FE 개발자로서 내가 구현해야할 부분이 무엇인지를 정확하게 알기 위해 찾아보다 https://han-um.tistory.com/17 에 정리된 내용을 발견했는데, 이해하기 쉽게 잘 정리 되어 있어 참고하였다.

내가 구현할 부분은

  • 서버에 ID / 비밀번호 보내기

  • 반환받은 AccessToken을 매 api 호출마다 헤더에 붙여 전송하기

  • AccessToken의 만료 기간이 지나거나, 30초 미만으로 남았다면, 백엔드의 RefreshToken을 붙여 Reissue 요청

  • Reissue 결과 반환된 AccessToken과 만료기간을 저장하여 다음 api 호출에 사용

크게 이렇게 구성되어있다.

여기서 AccessToken, RefreshToken, Reissue 새로운 3가지 키워드가 등장한다.





📌 Access Token

사용자가 서버에 로그인할 때 발급되는 토큰으로, 사용자가 서버에 인증된 상태를 유지하는 데 사용된다.
사용자가 서버의 보호된 리소스를 요청할 때마다 서버에 제공되며 짧은 유효기간을 가지고 있다.




📌 Refresh Token

Access Token의 만료 기간을 관리하는 데 사용되는 토큰으로,
Access Token이 만료되면 Refresh Token을 사용해 새로운 Access Token을 발급하는데 사용한다.




📌 Reissue

유효 기간이 만료된 Access Token을 새로 발급하는 프로세스로,
이를 통해 사용자는 서버에 다시 로그인할 필요 없이 새로운 Access Token을 발급 받을 수 있다.




토큰에 유효기간을 부여하는 이유❓
발급된 JWT는 삭제가 불가능한 특성을 가지고 있다. 이로 인해 토큰이 유출되거나 노출된 경우, 해당 토큰을 가진 사람은 권한을 획득할 수 있다. 따라서 토큰에 유효기간을 설정함으로써 유출된 토큰에 대한 접근 시간을 제한해 보안을 강화한다.
또한 토큰의 유효기관을 관리함으로써 서버는 주기적으로 클라이언트의 상태를 확인하고, 불필요한 토큰을 만료시켜 자원을 효율적으로 관리할 수 있다. 이를 통해 서버 자원을 낭비하지 않고 더 많은 사용자가 서비스를 이용할 수 있게 해준다.





📌 JWT 토큰 저장 위치

서버에 ID와 비밀번호를 보내 토큰을 반환받기까지 구현하였고, 이제 반환된 토큰을 저장해야한다.
토큰을 저장할 수 있는 위치는 크게 WebStorageCookie로 나뉘는데
두개의 차이점을 비교하여 어디에 저장할지 결정할것이다.

🔷 Web Storage

데이터를 서버가 아닌 클라이언트에 저장할 수 있도록 지원하는 기능으로
지속 기간에 따라 LocalStorageSessionStorage로 나뉜다.

  • Local Storage
    : 데이터를 브라우저에 반영구적으로 저장하며, 브라우저를 종료후 재시작해도 데이터가 남아있다.
      또한 다른 창과 브라우저를 통해서도 접근이 가능하다.

  • Session Storage
    : LocalStorage와 유사한 기능을 가지고 있으나 브라우저가 닫히면 데이터는 사라지게되며 다른 창과 브라우저의 데이터 공유 또한 불가능하다.

WebStorage는 모두 자바스크립트로 제어가 가능하기 때문에 XSS 공격에 취약해 노출될 경우 보안에 문제가 발생할 수도 있다.



XSS 공격이란
Cross Site Scripting의 줄임말로 공격자가 상대방의 브라우저에 스크립트가 실행되도록해 사용자의 세션을 가로채거나 웹사이트를 변조, 또는 악의적 콘텐츠 삽입이나 피싱 공격을 진행하는 것을 말한다.




웹사이트 접속시 접속자의 개인장치에 다운로드되고 브라우저에 저장되는 작은 텍스트 파일이다.
쿠키 또한 자바스크립트로 제어가 가능하지만 HTTP Only, Secure, SameSite와 같은 옵션들로 보안을 강화할 수 있다.

  • HTTP Only : 자바스크립트를 통한 쿠키 접근을 방지XSS 공격으로부터 쿠키를 보호한다. 이 설정을 사용하면 브라우저 내에서만 쿠키가 사용될 수 있다.

  • Secure : HTTPS 프로토콜에서만 쿠키를 전송하도록 한다. 이 설정은 네트워크를 통해 전송되는 쿠키를 암호화하여 중간에 있는 공격자로부터 정보를 보호한다.

  • SameSite : 쿠키를 어느 웹사이트로부터 요청이 왔는지를 제어하는 설정으로 CSRF 공격을 방지하는데 사용된다.



CSRF 공격이란
Cross-Site Request Forgery의 줄임말로 링크나 스크립트를 사용하여 사용자가 인증된 대상 사이트로 원하지 않는 HTTP 요청을 전송하는 것을 말한다.




🔷 저장할 위치

WebStorage는 데이터 용량이 크고, 세션이나 특정 시간에 상관 없이 영구적으로 데이터를 저장할 수 있지만 XSS 공격에 취약해 보안적 위험이 크다는 것이 단점이다.
반면 Cookie는 보안 옵션들을 통해 보안을 강화할 수 있으며 서버 요청시마다 자동으로 전송되어 클라이언트와 서버 간의 상태를 유지하기에 용이하다. 다만 도메인당 쿠키 저장 용량에 제한이 있다는게 단점이다.
토큰은 무엇보다 보안이 중요한 요소이기 때문에 보안 옵션을 활용한 쿠키에 저장하는 것이 바람직하다고 생각된다. 이를 통해 토큰이 안전하게 보호되고, 클라이언트와 서버간의 안전한 통신이 유지될 수 있기 때문이다.




지금까지 이론적인 부분들을 살펴보았으니 다음 글부터는 본격적으로 토큰 저장을 구현해보겠습니다.






참고
https://velopert.com/2389
https://velog.io/@seung7152/React-JWT-%ED%86%A0%ED%81%B0-%EC%A0%80%EC%9E%A5-%EC%9C%84%EC%B9%98

profile
새로움을 두려워 하지 않는 도전하는 프론트엔드 개발자👩‍💻

0개의 댓글