들어가면서
이전 프로젝트를 진행하면서 OAuth 2.0과 Spring Security를 이용한 회원 기능을 구현한 경험이 있습니다. 그러나 여러 블로그 포스팅을 찾아보면서 OAuth 2.0과 JWT, 그리고 Spring Security를 조합하여 더욱 강력한 인증 및 인가 시스템을 구현한 애플리케이션을 많이 보았습니다. 이에 제가 사전에 충분한 지식을 습득하지 못한 상황에서 새로운 프로젝트 도전하게 되었습니다.
세션 기반 인증과 토큰 기반 인증
이전 프로젝트에서 Spring Security는 기본적으로 세션 기반 인증을 제공해주기 때문에 사용자의 정보를 담은 세션을 생성하고 저장해서 인증하는 방식을 사용했었습니다. 이를 세션 기반 인증이라 부르며, 세션에 접근만 하면 사용자의 정보를 쉽게 가져올 수 있다는 장점을 가집니다.
세션 기반 인증은 클라이언트로부터 요청을 받으면 클라이언트의 상태 정보를 세션에 저장하여 유지해야하기 때문에 Stateful 합니다. 또한 세션에 사용자 정보를 담아두기 때문에 서버에 무리를 줄 수 있다는 단점을 가지고 있습니다.
무상태성(Stateless)
토큰 기반 인증은 서버가 유니크한 토큰을 생성하여 클라이언트에게 제공하면 클라이언트는 해당 토큰을 갖고 있다가 토큰과 함께 요청을 하게 됩니다. 즉 서버는 토큰을 발급만 해줄 뿐 따로 저장하여 유지 할 필요가 없으며, 클라이언트만 가지고 있기 때문에 Stateless 한 장점을 가지고 있습니다.
확장성
Stateless 한 토큰 기반 인증은 확장성에도 영향을 줍니다. 예를 들어 구매 물건을 담아두는 서비스가 있고, 결제를 위한 서버가 서로 분리되어 있다고 가정해보겠습니다. 세션 기반 인증은 각각 API에 인증을 해야하는 것과 다르게 토큰 기반 인증은 토큰을 가지고 있는 주체가 서버가 아닌 클라이언트이기 때문에 하나의 토큰을 통해 각 서버에 요청을 보낼 수 있게 됩니다.
무결성
토큰은 발급한 이후 토큰 정보를 변경하는 행위를 할 수 없습니다. 만약 누군가 토큰을 임의로 조작하게 된다면 서버에서 유효하지 않는 토큰으로 판단하게 됩니다. 즉 토큰의 무결성을 보장합니다.
토큰 기반 인증 JWT
JWT(Json Web Token)란 인증에 필요한 정보를 암호화시킨 토큰을 의미합니다.
서버에게 발급 받은 JWT는 HTTP 요청 헤더 중 Authorization에 (Bearer + JWT 토큰 값)으로 담아 보내게 되면 JWT 토큰이 유효한지 검증 후, 해당 사용자의 정보를 얻어 요청한 API에 권한이 있는 지 확인 후 응답을 보내줍니다.
JWT의 구조
JWT는 .을 기준으로 헤더(header), 내용(payload), 서명(signature)으로 구성되어 있습니다.
헤더(header)는 암호화 알고리즘(alg)과 토큰의 타입(typ)으로 구성되어 있으면 다음의 경우 HS256 해싱 알고리즘과 JWT를 사용한다는 의미입니다.
내용(payload)은 토큰과 관련된 정보를 담는 곳으로 각 내용의 한 조각을 클레임(Claim)이라 부르며, 키값의 한 쌍으로 이뤄져있습니다. 클레임은 등록된 클레임, 공개 클레임, 비공개 클레임으로 3가지 유형을 가집니다.
위 iss(토큰 발급자), sub(토큰 제목), iat(발급시간), exp(만료시간)는 등록된 클레임으로 필수는 아니지만 미리 정의되어 있어 권장되는 클레임의 집합입니다. 등록된 클레임의 정보는 해당 링크로 보시면 됩니다.
이 외 name은 비공개 클레임이면 사용자 정의 클레임입니다.
서명(signature)은 토큰을 인코딩하거나 유효성 검증을 위해 생성됩니다. 즉 토큰 값이 도중에 변경되지 않았는지 확인하는 데 사용됩니다.
헤더 + 내용 + 서명을 합쳐 인코딩을 진행하면 아래와 같은 토큰 값이 나오게 됩니다. JWT를 직접 인코딩 및 디코딩을 해보고 싶다면 JWT 공식 사이트를 통해 만들어보실 수 있습니다.
토큰 기반 인증 JWT는 세션 기반 인증보다 좋은 방식인가?
토큰 방식을 공부하면서 세션 인증보다 좋은 점만 있다면 왜 세션 인증 방식을 아직 사용하고 있는 가에 대한 질문이 생겼습니다. 정말 그렇다면 세션 기반 인증은 점점 사라질 기술이기 때문입니다.
모든 기술은 기존 기술의 문제점을 개선하고 발전시키지만, 그 과정에서 항상 트레이드오프가 존재합니다. 따라서 어떤 기술이든지 단순히 정해진 답이 있는 것이 아니라, 사용하는 상황과 목표에 따라 적절하게 선택되어야 합니다.
즉 이러한 고민과 애플리케이션에 맞는 방향을 가진 기술을 선택할 줄 알아야 하는 것이 개발자의 역량이라고 생각합니다.
JWT 토큰의 장점을 나열하면 아래와 같습니다.
- 무상태(Stateless)
- 확장성이 우수합니다.
- 무결성하기 때문에 위변조를 방지합니다.
단점도 나열해보겠습니다.
- 이미 발급된 JWT 토큰은 변경할 수 없습니다.
- JWT 토큰이 탈취될 경우 유효기간을 바꿀 수 없기 때문에 기간이 지나기 전까지 악의적으로 사용될 우려가 있습니다.
- 토큰 방식 중 JWT 토큰의 길이가 작은 편이지만 세션 방식에 비해 길며 서버의 자원 낭비가 발생될 수 있습니다.
단점 중 JWT 토큰이 탈취되는 문제는 API를 요청하기 위한 JWT 토큰의 유효시간을 짧게 만들고, 이후 만료되면 재발급할 수 있는 전략을 취해 보완했습니다. 이 부분은 다른 포스팅을 통해 다루도록 하겠습니다.
다음 포스팅으로 이동
Spring Security + JWT + OAuth 2.0 회원 기능(2) - JWT 설정
JWT.IO
JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.
jwt.io
OAuth 2.0 + JWT + Spring Security로 회원 기능 개발하기 - JWT 개념과 Security 기본 설정
두번의 프로젝트를 통해 회원 기능을 구현할때는 사용자가 로그인을 성공하면 사용자 정보를 객체에 담아 Session 저장소에 보관하는 방식으로 처리해왔습니다.Session에 회원객체를 저장하면, 어
velog.io
Spring Security + JWT를 이용한 자체 Login & OAuth2 Login(구글, 네이버, 카카오) API 구현 (1) - 회원(User) 관
들어가기 전 처음 프로젝트 진행 시, 아무것도 모르던 상태에서 처음으로 만들어야겠다고 생각이 든 기능이 로그인 기능이었습니다. 처음부터 자체 Login과 OAuth2 Login(소셜 로그인)을 같이 구현해
ksh-coding.tistory.com
'Spring > Spring Security' 카테고리의 다른 글
Spring Security + JWT + OAuth 2.0 회원 기능(5) - OAuth 2.0 인증 서버 등록 (0) | 2024.03.11 |
---|---|
Spring Security + JWT + OAuth 2.0 회원 기능(4) - OAuth 2.0 개념 (1) | 2024.03.11 |
Spring Security + JWT + OAuth 2.0 회원 기능(3) - JWT 테스트 코드 (0) | 2024.03.11 |
Spring Security + JWT + OAuth 2.0 회원 기능(2) - JWT 기능 구현 (1) | 2024.03.11 |
Spring Security 6.1, xxx is deprecated and marked for removal (1) | 2024.02.26 |