HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
👻
개발 기록
/
📚
CS 스터디
/
📚
Cookie, OAuth 2.0
📚

Cookie, OAuth 2.0

인증 관련 라이브러리를 잘 활용하기 위해 인증 기능을 구현하는 방법에 대한 기본적인 원리를 알아보자!

HTTP 쿠키

  • 쿠키는 HTTP 프로토콜에 포함되어 있는 웹브라우저 기술.
  • HTTP 쿠키(웹 쿠키, 브라우저 쿠키)는 서버가 사용자의 웹 브라우저에 전송하는 작은 데이터 조각
  • 라우터는 그 데이터 조각들을 저장해 놓았다가, 동일한 서버에 재 요청 시 저장된 데이터를 함께 전송.
  • 웹서버의 정보를 웹브라우저에 저장해서 개인화, 인증, 사용자 추적 등의 기능을 구현할 수 있도록 함.
  • 쿠키는 두 요청이 동일한 브라우저에서 들어왔는지 아닌지를 판단할 때 주로 사용.
  • 이를 이용하면 사용자의 로그인 상태를 유지할 수 있음.
  • 상태가 없는 HTTP 프로토콜에서 상태 정보를 기억시켜주기 때문.

용도

  • Session management : 서버에 저장해야 할 로그인, 장바구니, 게임 스코어 등의 정보 관리.
  • Personalization : 사용자 선호, 테마 등의 세팅.
  • Tracking : 사용자 행동을 기록하고 분석하는 용도.

쿠키로 로그인 기능을 만들어도 될까?

정답은 NO!
  • 과거엔 클라이언트 측에 정보를 저장할 때 쿠키를 주로 사용했지만, 보안이 약하며 모든 요청마다 쿠키가 함께 전송되기 때문에 성능이 떨어질 수 있음.
  • 정보를 클라이언트 측에 저장하려면 Modern APIs의 종류인 웹 스토리지 API (localStorage와 sessionStorage) 와 IndexedDB를 사용하기.

쿠키 만들기

Set-Cookie

Set-Cookie: <cookie-name>=<cookie-value>

Cookie 헤더

var http = require('http'); var cookie = require('cookie'); http.createServer(function(request, response){ var cookies = {}; if(request.headers.cookie !== undefined){ cookies = cookie.parse(request.headers.cookie); } response.writeHead(200, { 'Set-Cookie':['yummy_cookie=choco', 'tasty_cookie=strawberry'] }); response.end('Cookie!!'); }).listen(3000);
쿠키에 언어설정을 담은 예시
쿠키에 언어설정을 담은 예시
쿠키에 세션 아아디를 담은 예시
쿠키에 세션 아아디를 담은 예시

Cookie 헤더

  • Session cookie : 웹브라우저를 끄면 사라지는 휘발성 쿠키. 상단 쿠키 예시만큼 쓰면 세션 쿠키.
  • Permanent cookie :
    • 브라우저 재시작 시 세션을 복원해 세션 쿠키가 무기한 존재할 수 있음.
    • 웹브라우저를 꺼도 사라지지 않는 쿠키.
    • 단 Expires 속성에 명시된 날짜에 삭제되거나, Max-Age 속성에 명시된 기간 이후에 삭제됨.
      • Set-Cookie: id=a3fWa; Expires=Wed, 21 Oct 2015 07:28:00 GMT;
var http = require('http'); var cookie = require('cookie'); http.createServer(function(request, response){ var cookies = {}; if(request.headers.cookie !== undefined){ cookies = cookie.parse(request.headers.cookie); } response.writeHead(200, { 'Set-Cookie':[ 'yummy_cookie=choco', 'tasty_cookie=strawberry', `Permanent=cookies; Max-Age=${60*60*24*30}` ] }); response.end('Cookie!!'); }).listen(3000);
Expires에 날짜가 지정된 모습.
Expires에 날짜가 지정된 모습.

Secure과 HttpOnly 쿠키

  • Secure : 웹브라우저와 웹서버가 https로 통신하는 경우만 웹브라우저가 쿠키를 서버로 전송하는 옵션.
  • HttpOnly : XSS(크로스 사이트 스크립팅) 공격을 방지하기 위해, JS의 document.cookie를 이용해서 쿠키에 접속하는 것을 막는 옵션.
  • 쿠키를 훔쳐가는 행위를 막기 위한 방법.
  • 하지만 Secure일지라도 실질적인 보안은 제공하지 않기 때문에 민감한 정보는 절대 쿠키에 저장되면 안됨.
var http = require('http'); var cookie = require('cookie'); http.createServer(function(request, response){ var cookies = {}; if(request.headers.cookie !== undefined){ cookies = cookie.parse(request.headers.cookie); } response.writeHead(200, { 'Set-Cookie':[ 'yummy_cookie=choco', 'tasty_cookie=strawberry', `Permanent=cookies; Max-Age=${60*60*24*30}` 'Secure=Secure; Secure', 'HttpOnly=HttpOnly; HttpOnly' ] }); response.end('Cookie!!'); }).listen(3000);
HttpOnly 플래그가 적혀있는 쿠키는 JS로 확인할 수 없음.
HttpOnly 플래그가 적혀있는 쿠키는 JS로 확인할 수 없음.

path & domain

  • 쿠키의 유효범위를 정의함 → 어떤 URL을 쿠키가 보내야 하는지를 정의.
  • 만약 Path=/docs이 설정되면, 다음의 경로들은 모두 매치됨.
    • /docs
    • /docs/Web/
    • /docs/Web/HTTP
  • 만약 Domain=mozilla.org이 설정되면, 쿠키들은 developer.mozilla.org와 같은 서브도메인 상에 포함함.
var http = require('http'); var cookie = require('cookie'); http.createServer(function(request, response){ var cookies = {}; if(request.headers.cookie !== undefined){ cookies = cookie.parse(request.headers.cookie); } response.writeHead(200, { 'Set-Cookie':[ 'yummy_cookie=choco', 'tasty_cookie=strawberry', `Permanent=cookies; Max-Age=${60*60*24*30}` 'Secure=Secure; Secure', 'HttpOnly=HttpOnly; HttpOnly' 'Path=Path; Path=/cookie', 'Doamin=Domain; Domain=test.o2.org' ] }); response.end('Cookie!!'); }).listen(3000);

OAuth 2.0

  • 사용자가 가입된 서비스의 API에 접근하기 위해서는 사용자로부터 권한을 위임 받아야 함.
  • 이 때 사용자의 패스워드 없이도 권한을 위임 받을 수 있는 방법이 필요.
  • 이를 위해서 고안된 기술이 OAuth임.
  • 오늘날 카카오, 구글, 페북 등 많은 API들이 OAuth를 통해서 상호 연동을 지원하고 있음.

왜 OAuth를 이용해야 할까?

  • SNS 로그인을 시도할 때 불안요소가 존재함.
    • 유저(Resource Owner) : 내 SNS 계정 통채로 줄 수 없는걸...?
    • 서비스(Client) : SNS 계정 가져갔다가 뺏기면 어떻게 책임지지..ㅜ
    • SNS(Resource Server) : 우리 고객의 소중한 정보인데!?
      • 이때 인증을 전담하는 Authorization Server와 자원의 제공자인 Resource Sever로 나뉨.
  • 이에 따라 SNS가 유저의 요청에 따라 accessToken을 발급해줌으로써 필요한 인증 기능만 제공할 수 있게 됨.
💡
OAuth를 통해 accessToken을 발급하는 원리를 파악해보자!

등록

  • Resource Server에 도메인 주소 등 정보를 입력하면 다음과 같은 정보를 받음.
    • Client ID : 어플리케이션 식별자.
    • Client Secret : 이에 대한 비밀번호(유출 X).
    • Authorized redirect URIs : Resource Server가 해당된 주소만 정보를 전달함.

인증 과정

notion image

Owner와 Server가 진행

  1. Owner가 Client로 접속 시 Server를 사용해야 함. ex) 댓글을 남김
  1. Server가 로그인을 요구함. ex) 구글로 로그인하기.
  1. 클릭시 다음과 같은 링크를 전달.
    1. https://resource.server/?client_id=1&scope=B,C&redirect_uri=https://client/callback
  1. 로그인을 하면 Server가 전달된 링크의 client와 uri 그리고 자신의 정보를 확인함.
  1. 같다면 Owner에게 scope에 대한 권한을 Client에게 부여할 것인지 메시지를 전달.
    1. notion image
  1. Sever는 접속을 허락한 Owner의 user id와 scope를 서버에 저장함.

Server와 Client가 진행

notion image
🚧
Server는 바로 accessToken을 발급하지 않고 인증과정을 한번 더 함. 3자 간의 거래니까!
  1. Server는 임시 비밀번호인 authorization code를 발급하고,
  1. 이를 Owner에게 전송함. Location은 해당 주소로 이동하란 뜻임.
    1. Location:https://client/callback?code=3
  1. Owner는 Server가 제공한 주소로 이동함.
  1. Client는 authorization code를 갖게 됨.
  1. Client는 Server에 다음의 주소를 가지고 접근함. 이때 secret도 전송하는 것임.
    1. //이 외에도 4가지 방법이 더 있음. https://resource.server/token?grant_type=authorization_code&code=3&redirect_uri=https://client/callback&client_id=1&client_secret=2
  1. Server는 Client가 전송한 값과 일치하는지 확인함.
  1. Server는 authorization code를 삭제하고 accessToken을 발급함.
  1. Client는 내부적인 곳에 accessToken을 저장함.
  1. Server는 accessToken, user Id를 비교하고 scope에 대해 접근을 허용함.
💡
로그인뿐만 아니라 개인화된 정보를 지급하는 api에도 accessToken이 사용됨.

Refresh token

notion image
notion image
  • Access token은 수명이 있음.
  • Access token의 수명이 다했을 때 새로운 access token을 발급 받는 방법이 refresh token임.
 
 
참고자료 :
Using HTTP cookies
Node.js - Cookie & 인증
WEB2 - OAuth 2.0