안녕하세요. 초급 개발자 문문입니다.
이 글을 시작으로 개발하면서 공부하는 내용들을 이곳에 정리하고자 합니다. 잘 부탁드립니다!
이번 게시글은 Spring Security와 JWT를 이용하여 로그인을 구현하기에 앞서,
로그인에 사용될 JWT의 개념에 대해 정리했습니다.

📝 개념 정리
1. 인증(Authentication) / 인가(Authorization)
인증(Authentication)이란 로그인한 유저를 확인하는 것을 의미합니다. 아이디와 패스워드를 입력하여 로그인이 성공한다면 회원임이 인증된 것입니다.
인가(Authorization)란 사용자가 어떤 자원에 접근이 가능하고 동작이 가능한지 검증하는 것을 의미합니다. 예를 들어 쇼핑몰 사이트에 일반 회원과 관리자 회원이 둘 다 사이트의 회원이지만 받는 권한은 서로 다른 것처럼 말이죠.
2. JWT(JSON Web Token)
- JWT는 JSON 포맷을 이용하여 사용자의 속성을 저장하는 Claim 기반의 Web 토큰입니다.
JWT의 구조
HEADER(헤더). PAYLOAD(내용). SIGNATURE(서명)
JWT는 위와 같이 헤더, 내용, 서명으로 구성되어 있습니다.
▷ HEADER
- 헤더에서는 해시 알고리즘과 토큰의 타입을 정의할 수 있습니다.
- 서명을 해싱하기 위한 알고리즘을 지정합니다.
{
"alg": "HS256",
"typ": "JWT"
}
▷ PAYLOAD
- 내용을 전달하는 데이터를 포함합니다.
- 데이터의 각 Key를 Claim이라고 합니다.
{
"sub": "1",
"name": "Moon",
"iat": 1636989718
}
- Claim에는 registered , public , private 3가지 종류가 있습니다.
1. registered claim : 등록된 클레임
토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들을 의미합니다.
- iss: 토큰 발급자(issuer)
- sub: 토큰 제목(subject)
- aud: 토큰 대상자(audience)
- exp: 토큰 만료 시간(expiration), NumericDate 형식으로 되어 있어야 합니다 ex) 1480849147370
- nbf: 토큰 활성 날짜(not before)
- iat: 토큰 발급 시간(issued at), 토큰 발급 이후의 경과 시간
- jti: JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용
2. public claim : 공개 클레임
- 사용자가 자유롭게 정의가능한 클레임입니다.
- 공개용 정보를 위해 사용되고, 충돌 방지를 위해 URI 포맷을 이용합니다.
{"https://notes9190moon.tistory.com": true}
3. private claim : 비공개 클레임
- 정보를 공유하기 위해 만들어진 클레임입니다.
{
"access_token": access
}
▷ SIGNATURE
- 서명은 Base64로 인코딩 된 Header.Payload , 비밀 코드가 필요합니다.
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret
)
3. JWT 동작 흐름
로그인
- 사용자가 아이디, 비밀번호 혹은 소셜 로그인을 이용하여 서버에 로그인 요청을 보냅니다.
- 서버는 secret key를 사용해 json 객체를 암호화한 JWT 토큰을 발급합니다.
- JWT를 헤더에 담아 클라이언트로 보냅니다.
로그인 이후
- 클라이언트는 API 호출을 할 때마다 헤더에 JWT를 실어서 보냅니다.
- 서버는 API 헤더를 확인하여 사용자가 신뢰가능한지 체크하고, 인증이 되면 클라이언트로 응답을 보냅니다.
▷ HTTP의 특징은 한 번 통신이 일어나면 연결이 끊어진다는 것입니다. 그렇기 때문에 화면을 이동하여 새로운 API를 요청하면 다시 사용자 인증 과정을 거쳐야 하는 것입니다.
4. Access Token , Refresh Token
▷ Access Token
- Access Token은 사용자에 대한 정보를 담고 있어서 서비스에 접근할 수 있는 토큰을 의미합니다.
- Access Token이 있다면 위의 로그인 이후의 JWT 동작 흐름에서 API를 요청할 때마다 사용자 인증 과정을 거치지 않아도 됩니다.
▷ Refresh Token
- Refresh Token은 Access Token이 만료되었을 때 서버에서 이를 확인하고 새로운 액세스 토큰을 발급해 주기 위해 사용됩니다.
- Refresh Token은 서버의 db에 저장하기 때문에 클라이언트가 Access Token이 만료되어 API 호출하면 헤더에 들어있는 토큰을 확인하여 새로운 Access Token을 발급받습니다.
- Refresh Token을 이용하여 Access Token의 만료 시간을 짧게 잡아도 세션을 길게 유지시킬 수 있습니다.
5. 정리
✏️ 장점
- JWT는 사용자 인증과 로그인 유지를 위해 사용됩니다.
- JWT는 인증에 필요한 모든 정보를 담고 있기 때문에 별도의 저장소가 필요 없습니다.
- 확장성이 우수합니다.
- 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능합니다.
✏️ 단점
- Payload(내용)은 암호화가 되지 않아 중요한 정보는 담을 수 없습니다.
- 토큰을 탈취당하면 대처가 매우 어렵습니다.
마무리
JWT에 대해 공부하면서 개념을 정리해 보니 로그인할 때 인증과 인가를 진행하는 방식이 생각보다 복잡하다는 것을 알게 되었습니다. 또한 사용자의 접속 정보를 유지시키는 방법 Access Token과 Refresh Token에 대해 공부를 하고 보니 로그인 기능에 JWT를 사용하는 이유에 대해 알게 되었습니다. 다음장에는 Spring Security와 JWT를 결합하여 로그인 기능을 구현해 보도록 하겠습니다. 감사합니다!
피드백은 언제나 환영입니다 😀