
API를 작성하는데 있어서 로그인은 보안과 직결되기 때문에 가장 중요한 부분 중 하나이다.
그렇다면 로그인을 어떻게 안전하게 처리할 수 있을까?
그 부분에 대해 정리하고자 한다.
로그인 API가 보다 복잡한 이유는 우선 HTTP의 특성과 관련이 있다.
HTTP는 무상태성이라는 특성을 지니고 있는데, 클라이언트에 대한 이전 상태 정보 및 현재 통신 상태가 남아있지 않다. 따라서 이를 해결하고자 로그인 방식이 별도로 존재하는 것이다.
로그인 방식 3가지
- 쿠키 & 세션
- JWT
- OAuth
쿠키
- 클라이언트가 어떠한 웹사이트를 방문할 경우, 그 사이트가 사용하고 있는 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 정보 파일
- 무상태 환경에서 기억하고자 하는 데이터를 쿠키에 담고, 다음 번 요청 시에 쿠키를 요청에 함께 담아 보냄으로써 무상태를 극복

쿠키 인증 과정
- 사용자의 로그인 요청
- 로그인 성공 시, 서버는 쿠키를 생성
- 쿠키에 회원 정보를 담아 응답
- 사용자는 브라우저 저장소에 쿠키를 저장
- 다음 번 요청 시 쿠키를 요청에 함께 전달
- 서버는 쿠키를 보고 유저를 확인하고, 응답

쿠키 단점
- 보안에 취약하다: 쿠키가 전달될 때 개인 정보가 외부에 노출될 수 있다.
- 용량 문제: 많은 정보를 담을 수 없다.
- 브라우저 간 공유 불가능: 웹 브라우저마다 쿠키에 대한 지원 형태가 달라 공유가 불가능하다.
- 쿠키 사이즈: 쿠키의 사이즈가 커질수록 네트워크 부하가 심해진다.
세션
쿠키의 단점을 보완: 개인정보를 HTTP로 주고 받는 것은 위험하기 때문에, 세션은 이러한 비밀번호 등 클라이언트의 인증 정보를 쿠키가 아닌 서버 측에 저장하고 관리한다.

세션 인증 과정
- 사용자의 로그인 요청
- 로그인 성공 시, 서버에서 세션ID 생성 및 저장
- 쿠키에 생성한 세션 ID 정보를 담아 응답
- 사용자는 브라우저 저장소에 쿠키를 저장해두고, 다음 요청 시에 쿠키를 함께 전달
- 서버는 쿠키를 확인하고, 세션ID에 대응되는 유저가 누구인지 확인 후 응답

세션 장단점
장점
- 쿠키를 포함한 요청이 외부에 노출되더라도 유의미한 개인정보가 없기 때문에 안전
단점
- 해커가 쿠키를 중간에 탈취하여 마치 해당 유저인척 위장할 수 있다.
- 서버의 세션 저장소 구축, 관리 부담
JWT(JSON Web Token)
- 인증에 필요한 정보들을 암호화 시킨 토큰 → JWT 토큰이 쿠키를 대신
JWT 토큰 구조
- JWT는 .를 구분자로 나누어지는 3가지 문자열의 조합이다.

- Header
암호화할 해싱 알고리즘 및 토큰의 타입에 대한 정보 - Payload
토큰에 담을 정보. 주로 클라이언트의 고유 ID, 유효 기간 등을 포함한다. - Signature
인코딩된 Header와 Payload를 더한 뒤 비밀키로 해싱하여 생성한다. (위변조 여부 확인 목적)
JWT 인증 과정
- 클라이언트 로그인 요청
- 로그인 성공 시, 유저 정보 및 유효기간 등을 Payload에 담고, 비밀키를 사용해 Access Token(JWT)을 발급
- 서버는 생성한 JWT 토큰을 클라이언트에게 전달
- 클라이언트는 전달받은 토큰을 저장해두고, 요청할 때마다 토큰을 요청 헤터 Authorization에 포함시켜 함께 전달
- 서버는 받은 JWT의 헤더, 페이로드에 비밀키를 더해 암호화 + 암호화 값이 JWT의 Signature와 일치하는지 판단 후, 유효 기간 등을 확인하여 유효한 토큰인지 확인
- 유효한 토큰이라면 요청에 응답
토큰헤더: 암호화 알고리즘
+페이로드: 유저정보, 유효기간
+서버 비밀키
=시그니처
JWT 장단점
장점
- Header와 Payload와 비밀키를 가지고 Signature를 만들기 때문에 데이터 위변조를 막을 수 있음
- 인증 정보에 대한 별도의 저장소가 필요 없음
- 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능
- 모바일 환경에서도 정상적으로 동작(쿠키, 세션은 브라우저 내에서만 사용 가능)
단점
- 쿠키, 세션에 비해 데이터의 길이가 길어 네트워크 부하 가중
- Payload 자체는 암호화가 되지 않기 때문에 중요한 정보를 담을 수 없음
- 현재 로그인 중인지 여부를 알 수 없음
- 토큰을 탈취당하면 대처하기 어려움
JWT 단점 보완
→ Refresh Token을 추가로 두어 단점 보완
- 클라이언트 로그인 요청
- 로그인 성공 시, Access Token(긴 유효 기간)과 RefreshToken(짧은 유효 기간)을 발급 후 DB에 저장
- 서버는 생성한 Refresh 토큰을 클라이언트에 전달
- 클라이언트는 토큰을 저장해두고, 요청할 때마다 Refresh 토큰을 요청 헤더에 포함시켜 함께 전달
- 서버는 유효한 토큰인지 확인하여 응답. 이 때, 유효 기간이 지난 Refresh 토큰은 DB에서 Access Token과 비교 후 재발급 응답을 우선 수행
- 유효한 토큰이라면 요청에 응답
OAuth
인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준
→ 쉽게 말해 SNS 로그인 방식!
OAuth 참여자
- Resource Server: Client가 제어하고자 하는 자원을 보유하고 있는 서버 (ex. Google, Naver, Kakao)
- Resource Owner: 자원의 소유자(유저) (ex. Client 서비스를 통해 로그인하는 실제 유저)
- Client: Resource Server에 접속해서 정보를 가져오고자 하는 클라이언트 (ex. 내 서비스)
OAuth 인증 과정
Client 등록 및 설정
- Client는 Resource Server를 이용하기 위해 자신의 서비스를 등록
- 등록을 마치면, Client는 Client ID, Client Secret 등의 정보를 Resource Server로부터 제공 받는다.
(Resource Server는 Client ID, Client Secret 등의 정보로 Client를 구분)
Resource Server의 유저 인증과 권한 동의 요구
- Resource Owner가 소셜 로그인 버튼을 누르면, Client를 통해 Resource Server 로그인 페이지로 리다이렉션
- Resource Server에서는 요청한 Client의 ID, Secret 값 등을 확인하고 인증이 되면 로그인을 승인
로그인 승인 후, Resource Owner에게 Client로 정보 위임 권한을 줄 건지 질의 - Resource Owner가 권한 동의를 마치면, Resource Server는 Client가 등록한 리다이렉션 URL로 Authorization code를 담아 요청
Access Token 발급
- Client는 ID와 비밀키 및 발급 받은 Authorization Code 값을 Resource Server에게 직접 전달
- Resource Server는 정보를 검사한 다음, 유효한 요청이면 Access Token을 발급
Access Token 활용
- Client는 해당 토큰을 통해 Resource Server의 유저 자원을 사용하기 위한 API 호출 시 해당 토큰을 헤더에 담아 보냄
- Resource Server는 Access Token을 검증하고 유저 정보를 내려 줌
- Client는 받아온 유저 정보를 가지고 회원가입 및 로그인 기능 수행
※ Access Token: 유저의 정보를 볼 수 있는 권한을 준다.
이렇게 크게 3가지 로그인 방식에 대해 알아보았다. 보안이 가장 강력한 OAuth를 사용하면 가장 좋겠지만, 이는 로그인 시스템이 SNS에 종속된다는 것을 의미한다. 어떤 방식이든 장단점이 있는 법이다.
프로그램의 규모, 목적과 환경제약 등을 고려하여 가장 적합한 로그인 방식을 선정하는 것이 필요할 것 같다.
'Web > 정보' 카테고리의 다른 글
[Web] 웹 서비스 구조(Web Service Architecture) (0) | 2022.11.01 |
---|---|
[Web] HTTP(Hyper Text Transfer Protocol) 알아보기 (0) | 2022.10.24 |

API를 작성하는데 있어서 로그인은 보안과 직결되기 때문에 가장 중요한 부분 중 하나이다.
그렇다면 로그인을 어떻게 안전하게 처리할 수 있을까?
그 부분에 대해 정리하고자 한다.
로그인 API가 보다 복잡한 이유는 우선 HTTP의 특성과 관련이 있다.
HTTP는 무상태성이라는 특성을 지니고 있는데, 클라이언트에 대한 이전 상태 정보 및 현재 통신 상태가 남아있지 않다. 따라서 이를 해결하고자 로그인 방식이 별도로 존재하는 것이다.
로그인 방식 3가지
- 쿠키 & 세션
- JWT
- OAuth
쿠키
- 클라이언트가 어떠한 웹사이트를 방문할 경우, 그 사이트가 사용하고 있는 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 정보 파일
- 무상태 환경에서 기억하고자 하는 데이터를 쿠키에 담고, 다음 번 요청 시에 쿠키를 요청에 함께 담아 보냄으로써 무상태를 극복

쿠키 인증 과정
- 사용자의 로그인 요청
- 로그인 성공 시, 서버는 쿠키를 생성
- 쿠키에 회원 정보를 담아 응답
- 사용자는 브라우저 저장소에 쿠키를 저장
- 다음 번 요청 시 쿠키를 요청에 함께 전달
- 서버는 쿠키를 보고 유저를 확인하고, 응답

쿠키 단점
- 보안에 취약하다: 쿠키가 전달될 때 개인 정보가 외부에 노출될 수 있다.
- 용량 문제: 많은 정보를 담을 수 없다.
- 브라우저 간 공유 불가능: 웹 브라우저마다 쿠키에 대한 지원 형태가 달라 공유가 불가능하다.
- 쿠키 사이즈: 쿠키의 사이즈가 커질수록 네트워크 부하가 심해진다.
세션
쿠키의 단점을 보완: 개인정보를 HTTP로 주고 받는 것은 위험하기 때문에, 세션은 이러한 비밀번호 등 클라이언트의 인증 정보를 쿠키가 아닌 서버 측에 저장하고 관리한다.

세션 인증 과정
- 사용자의 로그인 요청
- 로그인 성공 시, 서버에서 세션ID 생성 및 저장
- 쿠키에 생성한 세션 ID 정보를 담아 응답
- 사용자는 브라우저 저장소에 쿠키를 저장해두고, 다음 요청 시에 쿠키를 함께 전달
- 서버는 쿠키를 확인하고, 세션ID에 대응되는 유저가 누구인지 확인 후 응답

세션 장단점
장점
- 쿠키를 포함한 요청이 외부에 노출되더라도 유의미한 개인정보가 없기 때문에 안전
단점
- 해커가 쿠키를 중간에 탈취하여 마치 해당 유저인척 위장할 수 있다.
- 서버의 세션 저장소 구축, 관리 부담
JWT(JSON Web Token)
- 인증에 필요한 정보들을 암호화 시킨 토큰 → JWT 토큰이 쿠키를 대신
JWT 토큰 구조
- JWT는 .를 구분자로 나누어지는 3가지 문자열의 조합이다.

- Header
암호화할 해싱 알고리즘 및 토큰의 타입에 대한 정보 - Payload
토큰에 담을 정보. 주로 클라이언트의 고유 ID, 유효 기간 등을 포함한다. - Signature
인코딩된 Header와 Payload를 더한 뒤 비밀키로 해싱하여 생성한다. (위변조 여부 확인 목적)
JWT 인증 과정
- 클라이언트 로그인 요청
- 로그인 성공 시, 유저 정보 및 유효기간 등을 Payload에 담고, 비밀키를 사용해 Access Token(JWT)을 발급
- 서버는 생성한 JWT 토큰을 클라이언트에게 전달
- 클라이언트는 전달받은 토큰을 저장해두고, 요청할 때마다 토큰을 요청 헤터 Authorization에 포함시켜 함께 전달
- 서버는 받은 JWT의 헤더, 페이로드에 비밀키를 더해 암호화 + 암호화 값이 JWT의 Signature와 일치하는지 판단 후, 유효 기간 등을 확인하여 유효한 토큰인지 확인
- 유효한 토큰이라면 요청에 응답
토큰헤더: 암호화 알고리즘
+페이로드: 유저정보, 유효기간
+서버 비밀키
=시그니처
JWT 장단점
장점
- Header와 Payload와 비밀키를 가지고 Signature를 만들기 때문에 데이터 위변조를 막을 수 있음
- 인증 정보에 대한 별도의 저장소가 필요 없음
- 토큰 기반으로 다른 로그인 시스템에 접근 및 권한 공유가 가능
- 모바일 환경에서도 정상적으로 동작(쿠키, 세션은 브라우저 내에서만 사용 가능)
단점
- 쿠키, 세션에 비해 데이터의 길이가 길어 네트워크 부하 가중
- Payload 자체는 암호화가 되지 않기 때문에 중요한 정보를 담을 수 없음
- 현재 로그인 중인지 여부를 알 수 없음
- 토큰을 탈취당하면 대처하기 어려움
JWT 단점 보완
→ Refresh Token을 추가로 두어 단점 보완
- 클라이언트 로그인 요청
- 로그인 성공 시, Access Token(긴 유효 기간)과 RefreshToken(짧은 유효 기간)을 발급 후 DB에 저장
- 서버는 생성한 Refresh 토큰을 클라이언트에 전달
- 클라이언트는 토큰을 저장해두고, 요청할 때마다 Refresh 토큰을 요청 헤더에 포함시켜 함께 전달
- 서버는 유효한 토큰인지 확인하여 응답. 이 때, 유효 기간이 지난 Refresh 토큰은 DB에서 Access Token과 비교 후 재발급 응답을 우선 수행
- 유효한 토큰이라면 요청에 응답
OAuth
인터넷 사용자들이 비밀번호를 제공하지 않고 다른 웹사이트 상의 자신들의 정보에 대해 웹사이트나 애플리케이션의 접근 권한을 부여할 수 있는 공통적인 수단으로서 사용되는, 접근 위임을 위한 개방형 표준
→ 쉽게 말해 SNS 로그인 방식!
OAuth 참여자
- Resource Server: Client가 제어하고자 하는 자원을 보유하고 있는 서버 (ex. Google, Naver, Kakao)
- Resource Owner: 자원의 소유자(유저) (ex. Client 서비스를 통해 로그인하는 실제 유저)
- Client: Resource Server에 접속해서 정보를 가져오고자 하는 클라이언트 (ex. 내 서비스)
OAuth 인증 과정
Client 등록 및 설정
- Client는 Resource Server를 이용하기 위해 자신의 서비스를 등록
- 등록을 마치면, Client는 Client ID, Client Secret 등의 정보를 Resource Server로부터 제공 받는다.
(Resource Server는 Client ID, Client Secret 등의 정보로 Client를 구분)
Resource Server의 유저 인증과 권한 동의 요구
- Resource Owner가 소셜 로그인 버튼을 누르면, Client를 통해 Resource Server 로그인 페이지로 리다이렉션
- Resource Server에서는 요청한 Client의 ID, Secret 값 등을 확인하고 인증이 되면 로그인을 승인
로그인 승인 후, Resource Owner에게 Client로 정보 위임 권한을 줄 건지 질의 - Resource Owner가 권한 동의를 마치면, Resource Server는 Client가 등록한 리다이렉션 URL로 Authorization code를 담아 요청
Access Token 발급
- Client는 ID와 비밀키 및 발급 받은 Authorization Code 값을 Resource Server에게 직접 전달
- Resource Server는 정보를 검사한 다음, 유효한 요청이면 Access Token을 발급
Access Token 활용
- Client는 해당 토큰을 통해 Resource Server의 유저 자원을 사용하기 위한 API 호출 시 해당 토큰을 헤더에 담아 보냄
- Resource Server는 Access Token을 검증하고 유저 정보를 내려 줌
- Client는 받아온 유저 정보를 가지고 회원가입 및 로그인 기능 수행
※ Access Token: 유저의 정보를 볼 수 있는 권한을 준다.
이렇게 크게 3가지 로그인 방식에 대해 알아보았다. 보안이 가장 강력한 OAuth를 사용하면 가장 좋겠지만, 이는 로그인 시스템이 SNS에 종속된다는 것을 의미한다. 어떤 방식이든 장단점이 있는 법이다.
프로그램의 규모, 목적과 환경제약 등을 고려하여 가장 적합한 로그인 방식을 선정하는 것이 필요할 것 같다.
'Web > 정보' 카테고리의 다른 글
[Web] 웹 서비스 구조(Web Service Architecture) (0) | 2022.11.01 |
---|---|
[Web] HTTP(Hyper Text Transfer Protocol) 알아보기 (0) | 2022.10.24 |