Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[24주차 1] 인증 방식 종류 #234

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
104 changes: 104 additions & 0 deletions joon/authorization/content.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Cookie

- Key-Value 형식의 String
- 크기가 4kB를 넘을 수 없다.
- 클라이언트가 어떤 웹사이트를 방문하면, 해당 사이트가 사용하는 서버를 통해 클라이언트의 브라우저에 설치되는 작은 기록 파일
- 방문 기록 등의 정보가 저장된다.

### 인증 방식

1. 브라우저가 서버에 요청을 보낸다.
2. 서버는 클라이언트의 요청에 대한 응답을 보낼 때, 클라이언트 측(브라우저)에 저장할 정보를 응답 헤더의 Set-Cookie에 담는다.
3. 이후, 클라이언트는 요청을 보낼 때마다 저장된 쿠키를 요청 헤더의 Cookie에 담아 보낸다.
1. 이를 통해 서버는 담긴 정보를 가지고, 이 요청의 클라이언트가 누군지 식별하거나 추천 광고를 띄워준다.

### 단점

- 보안에 취약하다.
- 요청 시에 쿠키에 저장된 값을 그대로 보내 유출, 조작 등의 위험이 존재한다.
- 용량 제한(4kB)으로 많은 정보를 저장할 수 없다.
- 브라우저마다 지원하는 쿠키의 형태가 달라 브라우저간 공유가 불가능하다.
- 쿠키의 사이즈(개수?)가 커질수록 네트워크의 부하가 커진다.
- 그만큼 클라이언트 별로 저장해서 전달 받을 정보가 많아 그런듯하다.

# Session

- 쿠키의 보안 이슈로 세션은 클라이언트의 중요 정보를 브라우저가 아닌 서버측에 저장하고 관리한다.
- 서버의 메모리나 로컬 파일, 데이터베이스 등에 저장한다.
- 세션 객체는 Key에 해당하는 Session ID와 이에 대한 Value로 구성된다.
- Value에는 세션 생성 시간, 마지막 접근 시간, 저장된 속성 등이 Map 형태로 저장된다.

### 인증 방식

1. 유저가 로그인을 하면 Session ID를 기준으로 세션이 서버 메모리 상에 저장된다.
2. 서버에서 브라우저의 쿠키에 Session ID를 저장한다.
3. 쿠키에 Session ID가 담겨있어, 브라우저는 모든 요청에 Session ID를 쿠키에 담아 전송한다.
4. 서버는 클라이언트가 보낸 Session ID와 서버에 저장된 Session ID를 비교하여 인증을 수행한다.

### 단점

- 쿠키에 정보가 직접적으로 들어가지는 않지만, Session ID를 가지고 클라이언트로 위장할 수 있다.
- 서버에 세션 정보를 저장하기 때문에 요청이 많아지면 부하가 커진다.

# Token

- 클라이언트가 서버에 접속하면 서버에서 해당 클라이언트에게 인증 토큰을 부여한다.
- 토큰 자체에 데이터가 들어있다.
- 토큰은 Unique하며 토큰을 발급받은 클라이언트는 또 다시 서버에 요청을 보낼 때, 요청 헤더에 토큰을 넣어 보낸다.
- 이때 서버에서 클라이언트로부터 온 토큰과 발급한 토큰을 비교하여 인증 과정을 처리한다.
- 세션과의 차이
- 세션은 서버에서 중요 정보를 가지고 있기 때문에 조회하는 과정이 필요하여 부하가 크다
- 토큰은 인증되었다는 의미로 서버가 아닌 클라이언트에 토큰을 저장하기 때문에 세션에서 서버가 저장소 역할을 했던 것에 비해 서버의 부하가 적다.

### 인증 방식

1. 사용자가 로그인을 하면 서버 측에서 클라이언트에게 Unique한 토큰을 발급한다.
2. 클라이언트는 발급받은 토큰을 쿠키나 스토리지에 저장하고, 서버에 요청을 보낼 때마다 해당 토큰을 요청 헤더에 포함하여 전달한다.
3. 서버는 클라이언트로부터 전달받은 토큰을 검증하고 요청에 응답한다.
4. 토큰에는 요청한 클라이언트의 정보가 담겨있어 서버는 따로 DB 조회 없이 바로 어떤 클라이언트가 요청을 보냈는지 알 수 있다.

### 단점

- 쿠키/세션보다 토큰 자체의 데이터 길이가 길기 때문에 인증 요청이 많아지면 부하가 커진다.
- Payload 자체는 암호화되지 않기 때문에 유저의 중요 정보는 담을 수 없다.
- 토큰이 유출되면 대처가 어렵다.
- 사용 기간에 제한을 두어 사용한다.

# JSON Web Token

> 유저를 인증하고 식별하기 위한 토큰 기반 인증

토큰 인증 방식은 세션과 달리 서버가 아닌 클라이언트 쪽에 토큰을 저장해두기 때문에 서버의 공간을 사용하던 세션과 달리 서버의 부담을 줄일 수 있다.

JWT의 큰 특징은 사용자의 권한 정보나 서비스를 이용하기 위한 데이터가 **토큰 자체에 포함(self-contained)**된다. 대신 데이터가 커지면 그만큼 토큰의 크기가 커질 수 있고, 토큰이 한번 발급된 이후에 사용자 정보가 변경이 된다면 재발급이 되지 않는 이상 토큰이 갱신되지 않는다.

JWT를 이용한 인증의 동작 방식은 다음과 같다.

![[https://velog.io/@sjy0917/Express로-로그인-구현하기-JWT](https://velog.io/@sjy0917/Express%EB%A1%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-JWT)](https://s3-us-west-2.amazonaws.com/secure.notion-static.com/e79bca3c-02ab-4ed7-8f9b-2f17c258f671/Untitled.png)

[https://velog.io/@sjy0917/Express로-로그인-구현하기-JWT](https://velog.io/@sjy0917/Express%EB%A1%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-JWT)

1. 클라이언트가 로그인을 통해 웹서비스 인증을 시도
2. 서버에서 서명된(signed) JWT를 생성
3. 서버는 생성한 토큰을 응답에 담아 클라이언트에게 전달
4. 이후, 클라이언트가 서버에 요청을 보낼 때 JWT를 항상 HTTP header에 첨부하여 요청
5. 서버에서 클라이언트가 보낸 요청에 담긴 JWT가 유효한지 검증
6. 응답

JWT에는 JSON 데이터를 Base64 URL-safe Encode를 통해 인코딩하여 직렬화한 것이 포함된다.

## JWT 구조

> Header, Payload, Signature로 구성되고, 각 요소는 `.` 으로 구분된다

### Header

- JWT에서 사용할 타입과 해시 알고리즘의 종류가 담겨있다.

### Payload

- 서버에서 첨부한 사용자 권한 정보와 서비스를 이용하기 위한 데이터가 담겨있다.

### Signature

- Header, Payload를 Base64 URL-safe Encode를 한 후, Header에 명시된 해시 알고리즘을 적용하고, 개인키(Private Key)를 통해 서명된 전저서명이 담겨있다.