본문 바로가기
프론트엔드

브라우저 인증 방식(쿠키, 세션, 토큰, JWT 등)

by 민초의지배자 2025. 9. 9.

본문 이해 위한 사전 지식

 

인증(authentication)과 인가(Authorizion)
- 인증은 사용자가 주장하는 id와 비밀번호가 맞는지 확인하는 과정으로 주로 로그인 절차를 통해 수행된다,
- 인가는 인증된 사용자가 특정 리소스에 접근할 권한이 있는지를 확인하는 절차이다. 

Http의 비상태성(Stateless)
- Http는 요청 간의 상태를 저장하지 않는 Stateless 프로토콜이다.
- 지속적인 인증이 필요한 경우 세션또는 토큰 기반 방식으로 인증상태 유지해야함

 

 

1. HTTP 인증 방식 소개
- 웹 어플에서 보안은 매우 중요한 요소다, 특히 사용자 인증은 앱의 보안을 강화하는데 필수이다. 그 중 두가지가 basic auth와 bearer token이다.

- Basic auth는 가장 간단한 형태의 http 인증 방식으로 , 클라이언트가 서버에 요청을 보낼때 http 헤더에 사용자의 아이디와 비밀번호를 Base64로 인코딩해서 전송 방식. 
- Bearer Token은 OAuth와 같은 인증 서버를 사용해 엑세스토큰을 이용해 인증하는 방식이다.

- 왜냐면 Basic Auth는 간단하고 구현이 쉬운 반면, 보안이 강화된 환경에서만 사용해야 하기 때문이다.

- 반면 Bearer Token은 보안성이 높아 중요한 데이터나 기능을 보호하는 데 적합하다.



2. Basic Auth의 개념과 사용 방법
-Basic auth는 가장 간단한 형태의 http 인증 방식으로 , 클라이언트가 서버에 요청을 보낼때 http 헤더에 사용자의 아이디와 비밀번호를 Base64로 인코딩해서 전송 방식. 

- 다음과 같이 HTTP 요청 헤더에 추가 가능
Authorization: Basic dXNlcm5hbWU6cGFzc3dvcmQ=
- 왜냐면 Base64 인코딩은 단순한 인코딩 방식으로, 데이터를 암호화하지 않는다
따라서 HTTPS와 같은 보안이 강화된 환경에서 사용해야함

-Basic Auth의 단점은 요청할 때마다 아이디와 비밀번호를 전송해야 하므로 보안에 매우 예민하거나 민감한 어플에서는 적합하지 않다. 또한 암호화가 아니기에
네트워크에서 쉽게 읽힐 수 있다.
따라서 반드시 HTTPS를 사용해 데이터를 암호화해야하며. HTTPS는 SSL을 사용해 데이터를 암호화해서 전송하는 방법으로 데이터 탈취나 변조를 방지해준다



3. Bearer Token의 개념과 사용 방법
- Bearer Token은 OAuth와 같은 인증 서버를 사용해 엑세스 토큰을 이용해 인증하는 방식으로 보안성이 높아 중요한 데이터나 기능을 보호하는데 적합하다.
- Bearer Token을 사용하려면 우선 인증 서버에서 엑세스 토큰을 발급받아야한다. 클라이언트는 이 토큰을 HTTP요청 헤더에 포함해 서버로 전송한다.
Authorization: Bearer {access_token}

- 왜냐면 Bearer Token은 서버에서만 해석하고 검증할 수 있어 보안성이 강하기 때문이다. 이로 인해 전송 과정에서 데이터 보호가 가능하다.
Bearer Token의 장점은 보안성이 높아 중요한 데이터나 기능을 보호하는 데 적합하다는 점 또한 토큰 기반 인증 방식으로 요청할때마다 아이디 비밀번호 전송할 필요 없다.
- 다만 초기 설정이 복잡할 수 있다. 인증서버를 구축하거나 외부 인증 서비스 이용해야 하므로


4. Basic Auth와 Bearer Token의 비교
- 둘은 각각 장단점이 있는데, Basic Auth는 간단하고 구현이 쉬운 반면, 보안이 강화된 환경에서만 사용해야 하며 Bearer token은 보안성이 높아 중요한 데이터나 기능을 보호하는 데 적합하다.
-Basic Auth는 요청시 매번 아이디와 비밀번호를 전송해야 하므로 보안에 매우 예민하거나 민감한 어플리케이션에서는 적합하지 않다. 또안 Base64인코딩은 암호화가 아니기에 네트워크에서 쉽게 읽힐 수 있다.

-Bearer token은 서버에서만 해석하고 검증할 수 있어 보안성이 강하고 이로인해 전송 과정에서 데이터 보호가 가능하며 토큰 기반 인증 방식이기에 요청할 때마다 아이디와 비밀번호를 전송할 필요가 없다. 하지만 인증 서버 구축, 외부인증 서비스 이용해야 하므로 초기 설정 복잡할 수 있다


 

Cookie / Session / Token 인증 방식 종류

보통 서버가 클라이언트 인증을 확인하는 방식은 대표적으로 쿠키,세션, 토큰 3가지 방식이 있다.

JWT를 배우기 앞서 우선 쿠키와 세션의 통신 방식을 간단하게 알아보자

 


 1. 쿠키

1) cookie
 - 쿠키는 key-value 형식의 문자열 덩어리이다. 클라이언트가 어떤 웹사이트 방문할 경우 그 사이트가 사용하고 있는 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 정보 파일이다. 

2) 쿠키 인증 방식
- 브라우저(클라이언트)가 서버에 요청을 보낸다
- 서버는 클라이언트의 요청에 대한 응답 작성시 , 클라이언트 측에 저장하고 싶은 정보를 응답 헤더의 set-cookie에 담는다.
- 이후 해당 클라이언트는 요청 보낼 때마다, 매번 저장된 쿠키를 요청 헤더의 cookie에 담아 보냄
- 서버는 쿠키에 담긴 정보를 바탕으로 해당 요청의 클라이언트가 누군지 식별하거나 정보 바탕으로 추천 광고를 띄우거나 한다.
- 쿠키 방식의 단점은 보안에 취약하다는 것 ,요청 시 쿠키의 값을 그대로 보내기때문에 유출 및 조작 당할 위험이 존재하고 쿠키에는 용량 제한이 있어 많은 정보를 담을 수 없다. 브라우저간 공유가 불가능하고 쿠키 사이즈 커질수록 네트워크에 부하가 심해진다.

2. Session 인증


- 이러한 쿠키의 보안적 이슈 때문에 세션은 비밀번호등 클라이언트의 민감 인증 정보를 서버측에 저장하고 관리한다. 
- 세션 객체는 key에 해당하는 session id와 이에 대응하는 value로 구성되어 있다. value에는 세션 생성 시간, 마지막 접근 시간 밎 user가 저장한 속성등이 map형태로 저장된다.

-인증 순서 
  - 유저가 웹사이트에서 로그인하면 세션이 서버 메모리상에 저장됨 , 이때 세선을 식별하기 위한 Session Id를 기준으로 정보 저장함
  - 서버에서 브라우저에 쿠키에다가 Session Id를 저장함
  - 쿠키에 정보가 담겨있기 때문에 브라우저는 해당 사이트에 대한  모든 request에 session id를 쿠키에 담아 전송한다.
- 서버는 클라이언트가 보낸 session id와 서버 메모리로 관리하고 있는 session id를 비교하여 인증을 수행한다.

session 방식의 단점
- 쿠키를 포함한 요청이 외부에 노출되더라고 세션 id 자체는 유의미한 개인정보를 담고 있지 않음 하지만 해커가 세션 id 자체 탈취해 클라이언트인척 위장 가능성이 존재
- 서버에서 세션 저장소를 사용하므로 요청 많아지면 서버에 부하가 심해짐

3. Token인증


- 토큰 기반 인증 시스템은 클라이언트가 서버에 접속시 서버에서 해당 클라이언트에게 인증되었다는 의미로 토큰을 부여한다, 이 토큰은 유일하며 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼때 헤더에 토큰을 심어서 보내면 서버는 이 받은 토큰을 제공한 토근과의 일치 여부 체크해 인증 과정을 거친다.

- 기존의 세션기반 인증은 서버가 파일이나 데이터 베이스에 세션정보를 가지고 있어야 하고 이를 조회하는 과정이 필요하기 때문에 많은 오버헤드가 발생 하지만 토큰은 세션과 달리 서버가 아닌 클라이언트에 저장되기에 메모리나 스토리지 등을 통해 세션을 관리했던 서버의 부담을 덜 수 있다.
토큰 자체에 데이터가 들어있기 때문에 클라이언트에서 받아 위조되었는지만 판별만 하면 되기 때문이다.

[서버 기반 vs 토큰 기반]서버(세션) 기반 인증 시스템서버의 세션을 사용해 사용자 인증을 하는 방법으로 서버측(서버 램 or 데이터베이스)에서 사용자의 인증정보를 관리하는 것을 의미한다.그러다 보니, 클라이언트로부터 요청을 받으면 클라이언트의 상태를 계속에서 유지해놓고 사용한다.(Stateful) 이는 사용자가 증가함에 따라 성능의 문제를 일으킬 수 있으며 확장성이 어렵다는 단점을 지닌다.토큰 기반 인증 시스템이러한 단점을 극복하기 위해서 "토큰 기반 인증 시스템"이 나타났다.인증받은 사용자에게 토큰을 발급하고, 로그인이 필요한 작업일 경우 헤더에 토큰을 함께 보내 인증받은 사용자인지 확인한다.이는 서버 기반 인증 시스템과 달리 상태를 유지하지 않으므로 Stateless 한 특징을 가지고 있다.

- 토큰 인증 방식 :
사용자가 아이디와 비밀번호로 로그인한다. - 서버측에서 사용자에게 유일한 토큰을 발급- 클라이언트는 서버측에서 전달받은 토큰을 쿠키나 스토리지에 저장해 두고ㅡ 서버에 요청할 때마다 해당 토큰을 http 요청 헤더에 포함시켜 전달 - 서버는 이 토큰을 검증하고 응답, 토큰에는 요청한 사람의 정보가 담겨있기에 서버는 db를 조회하지 않고 누가 요청하는지 알수 있다.

토큰 방식의 단점 :
쿠키 세션과 다르게 토큰 자체의 데이터 길이가 길어, 인증 요청이 많아질수록 네트워크 부하
Payload 자체는 암호화 되지 않기에 유저의 중요한 정보는 담을 수 없다,
 토큰을 탈취당하면 대처하기 어려움 따라서 사용기간 제한을 설정하는 방식으로 극복 


 

 

4. JWT (Json Web Token) 이란?


 1) 개념
  - Jwt는 토큰 기반 인증에서 사용되는 대표적인 토큰 포맷이다.
  - json 데이터를 Base64 url-safe 방식으로 인코딩하여 직렬화된 토큰이다.
  - JWT 기반 인증은  JWT 토큰을 HTTP 헤더에 실어 서버가 클라이언트를 식별하는 방식이다.
  - 토큰 내부에는 위변조 방지를 위해 개인키를 통한 전자서명도 들어있다. 따라서 사용자가 JWT를 서버로 전송하면 서버는 서명을 검증하는 과정을 거치게 되며 검증이 완료되면 요청한 응답을 들려준다. 
 
2) 구조
- JWT는 . 을 구분자로 나누어지는 세 가지 문자열의 조합이다
- 좌측부터 Header, Payload, Signature를 의미
- Header에는 JWT에서 사용할 타입과 해시 알고리즘의 종류가 담겨있으며, Payload는 서버에서 첨부한 사용자 권한 정보와 데이터가 담겨있다. 
- 마지막으로 Signature에는 Header, Payload를 base URL - safe Encode를한 이후 Header에 명시된 해시함수를 적용하고, 개인키로 서명한 전자서명이 담겨있다. 
- 실제 디코딩된 JWT는 다음과 같은 구조를 지닌다.

3) Header
- {
"alg"  : "HS256",
"typ"  : "JWT"
}

4) Payload
  토큰에서 사용할 정보의 조각들인 Claim이 담겨있다. (실제 JWT를 통해 알 수 있는 데이터)
  즉 서버와 클라이어트가 주고받는 시스템에서 실제로 사용될 정보에 대한 내용을 담고 있는 섹션이다.
- key-value 형식으로 이루어진 한쌍의 정보를 claim이라고 칭한다.
- {
"sub"  : "123456",
"name"  : "Jone Doe",
"lat" : 1516239022
}
6) 페이로드는 정해진 데이터 타입은 없지만 , 대표적으로 Registered claims, public claims, private claims 이렇게 세가지로 나뉜다.
{
  "jki": "1000",   // Registered Claim
  "jki": "123123123123123"   // Registered Claim
  "http://kevin.tistory.com": true, // public claim
  "username": "kevin" // prtivate claim
}

7) Registered Claim: 미리 정의된 클레임
- iss : 발행자
- exp : 만료 시간
- sub : 제목
- iat : 발행 시간
- jti : JWI ID
Public claims : 사용자가 정의할 수 있는 클레임 공개용 정보 전달을 위해 사용.
Private claims : 해당하는 당사자들 간에 정보를 공유하기 위해 만들어진 사용자 지정 클레임. 외부에 공개되도 상관없지만 해당 유저를 특정할 수 있는 정보들을 담는다

Signature
- 시그니처에서 사용하는 알고리즘은 헤더에서 정의한 알고리즘 방식을 활용한다.
- 시그니처의 구조는 (헤더 + 페이로드)와 서버가 갖고 있는 유일한 key값을 합친 것을 헤더에서 정의한 알고리즘으로 암호화를 한다. 

8) JWT 인코딩 / 디코딩 해보기
- 직접 JWT 토큰을 생성해 연습해보고 싶다면, 아래 공식 사이트에서 쉽게 JWT 토큰을 인코딩 하거나 디코딩 할 수 있다.
https://www.jwt.io/

9) JWT를 이용한 인증 과정
- 사용자가 ID,PW를 입력해 서버에 로그인 인증을 요청한다.
- 서버에서 클라이언트로부터 인증 요청을 받으면, header, payload, signature를 정의한다. header, payload, signature를 각각 base64를 한 번 더 암호화하여 JWT를 생성하고 이를 쿠키에 담아 클라이언트에게 발급한다.
- 클라이언트는 서버로부터 받은 JWT를 로컬 스토리지에 저장한다. (쿠키나 다른 곳에 저장할 수도 있음), api를 서버에 요청할때 authorization header에 access token을 담아서 보낸다.
- 서버는 클라이언트가 Header 에 담아서 보낸 JWT가 내 서버에서 발행한 토큰인지
일치 여부를 확인해 일치하면 인증 통과해주고 아니면 통과하지 않음
인증이 통과되면 페이로드에 들어있는 유저의 정보들을 select해서 클라이언트에 돌려줌
- 클라이언트가 서버에 요청했는데 만일 엑세스 토큰의 시간이 만료되면 클라이언트는 리프래시 토큰을 이용해 서버로부터 새로운 엑세스 토큰을 발급받음

10) 토큰 인증 신뢰성을 가지는 이유
- 유저 JWT: A(Header) + B(Payload) + C(Signature)일때 
- 다른 유저가 B를 임의로 수정 -> 유저 JWT: A + 'B' + C
- 수정한 토큰을 서버에 요청을 보내면 서버는 유효성 검사 시행
 유저 JWT: A + B' + C
 서버에서 검증 후 생성한 JWT: A + B' + C' => (signature) 불일치
- 대조 결과가 일치하지 않아 유저의 정보가 임의로 조작되었음을 알 수 있다.

- 즉 서버는 토큰 안에 들어있는 정보가 무엇인지 아는게 중요한게 아니라 해당 토큰이 유효한 토큰인지 확인하는 것이 중요하기에 클라이언트로부터 받은 JWT의 헤더, 페이로드를 서버의 key값을 이용해 시그니처를 다시 만들고 이를 비교하며 일치했을 경우 인증을 통과시킨다.

- jwt는 서명이 목적이다. base64로 암호화를 하기에 디버거를 사용해 인코딩된 JWT를 1초만에 복호화할수있다. 복호화 하면 사용자의 데이터를 담은 Payload부분이 그대로 노출되어 버림. 그래서 페이로드에는 비밀번호같은 민감한 정보는 넣지 말아야한다.
- 그렇다면 토큰 인증 방식이 빛 좋은 개살구라고 생각할 수도 있지만, 토큰의 진짜 목적은 정보 보호가 아닌 위조 방지이다.

11)JWT 장점
- header와 payload를 가지고 Signature를 생성하므로 데이터 위변조 막을 수 있다.
- 인증 정보에 대한 별도의 저장소가 필요없다.
- JWT는 토큰에대한 기본 정보와 전달한 정보 및 토큰이 검증되었을음 증명하는 서명 등 필요한 모든 정보를 자체적으로 지니고 있다.
-클라이언트 인증 정보를 저장하는 세션과 다르게, 서버는 무상태가 되어 서버 확장성이 우수해질 수 있다.
- 토큰 기반으로 다른 로그인 시스템에 접근 밎 권한 공유가 가능하다(쿠키와 차이)
- OAuth의 경우 Facebook, google 등 소셜 계정을 이용해 다른 웹서비스에서도 로그인을 할 수 있다.
- 모바일 어플리케이션 환경에서도 잘 동작한다. (모바일은 세션 사용 불가능)

12) JWT 단점
- Self-contained: 토큰 자체에 정보 담고 있으므로 양날의 검이 될 수 있다.

- 토큰 길이: 토큰의 Payload에 3종류의 클레임 저장하기에 정보가 많아질수록 토큰의
길이가 늘어가 네트워크에 부하 줄 수 있다.

Payload 인코딩 : payload 자체는 암호화 된 것이 아니라 BASE64로 인코딩 된 것이기 때문에, 중간에 Payload를 탈취하여 디코딩하면 데이터를 볼 수 있으므로, payload에 중요 데이터를 넣지 않아야 한다.

Store Token : stateless 특징을 가지기 때문에, 토큰은 클라이언트 측에서 관리하고 저장한다. 때문에 토큰 자체를 탈취당하면 대처하기가 어렵게 된다

JWT의 Access Token / Refresh Token

- 이 JWT도 제 3자에게 토큰 탈취 위험성이 있기 때문에, 현업에서는 Access Token, Refresh Token으로 나누어 인증하는 방식을 사용한다

- 이 둘다 JWT이다, 다만 토큰이 어디에 저장되고 관리되느냐에 따른 사용 차이일 뿐이다.
 1) Access Token : 클라이언트가 갖고잇는 실제로 유저의 정보가 담긴 토큰으로, 클라이언트에서 요청이 오면 서버에서 해당 토큰의 정보를 활용해 사용자 정보에 맞게 응답을 진행
2) Refresh Token : 새로운 Access Token을 발급해주기 위해 사용하는 토큰으로 짧은 수명을 가지는 Acess Token에게 새로운 토큰을 발급해주기 위해 사용. 해당 토큰은 데이터베이스에 유저 정보와 같이 기록

위에서도 말했듯이 JWT 인증 방식을 만약 Access Token 만을 이용하면, Access Token은 발급된 이후 서버에 저장되지 않고 클라이언트에 저장되어 토큰 자체로 검증을 하며 사용자 권한 인증을 진행하기 때문에, Access Token이 탈취되면 토큰이 만료되기 전 까지, 토큰을 획득한 사람은 누구나 권한 접근이 가능해지는 문제점이 있었다. 그래서 토큰의 유효 시간을 부여하여 탈취 문제에 대해 대응을 하기도 하지만, 만일 유효 기간이 짧을 경우 그만큼 사용자는 로그인을 자주해야 하는 번거로움이 있다.따라서 이러한 문제를 해결하기 위해 Refresh Token 이라는 추가적인 토큰을 활용하여 토큰을 이중 장막을 쳐서 보다 보안을 강화하는 식으로 보면 된다

출처: https://inpa.tistory.com/entry/WEB-📚-JWTjson-web-token-란-💯-정리 [Inpa Dev 👨‍💻:티스토리]

'프론트엔드' 카테고리의 다른 글

[JS] 함수에 대해서  (0) 2025.08.04
[프론트엔드]  (1) 2025.07.30
[HTTP] 상태 코드 정리  (1) 2025.07.30
프로젝트 진행 전 해야할 것들  (1) 2025.07.24

댓글