Skip to content

Commit 924766e

Browse files
committed
docs: 인증과 인가
1 parent 63e7863 commit 924766e

10 files changed

Lines changed: 208 additions & 0 deletions

File tree

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,208 @@
1+
---
2+
title: Authentication, Authorization 인증과 인가
3+
createdAt: 2024-05-12
4+
category: Web
5+
description: 웹 애플리케이션에서 인증(Authentication)과 인가(Authorization)의 개념과 차이점에 대해 알아봅니다. Session, JWT 등 다양한 인증방식과 CSRF 문제에 대해 알아봅니다
6+
comment: true
7+
---
8+
9+
# 인증과 인가가 필요한 이유
10+
11+
## REST API 의 Stateless 한 특성
12+
13+
우리는 웹 페이지를 개발할 때, REST API 를 이용해 서버와 통신을 진행합니다. <br />
14+
이때 REST API 는 HTTP 프로토콜 위에서 동작하게 되는데, HTTP 는 Stateless 한 특성을 가지고 있습니다.
15+
16+
> `Stateless` : Stateless (무상태) 는 서버가 클라이언트의 이전 상태를 보존하지 않는다는 의미입니다
17+
18+
따라서 <br />
19+
각각의 요청은 독립적으로 처리되고, 한번 요청에 대한 응답이 전송되면, 이전 상태를 기억하지 못합니다.
20+
21+
## 인증과 인가
22+
23+
이러한 HTTP 의 Stateless 한 특성 때문에, 각 요청은 사용자가 로그인했는지 여부를 서버에게 알려주어야 합니다. <br />
24+
그렇지 않으면... 페이지를 이동하거나, 인증이 필요한 API 에 접근을 할 때 마다 로그인을 진행해야 합니다
25+
26+
> `인증 (Authentication)` : 인증은 사용자의 신원을 검증하는 절차입니다. 특정 사이트에 권한이 주어진 사용자임을 아이디와 비밀번호를 통해 인증을 받음
27+
> `인가 (Authorization)` : 인증을 받은 사용자가 사이트의 서비스나 자원을 사용, 접근, 요청 등을 보낼 수 있는 권한이 있는지 확인하는 절차입니다.
28+
29+
따라서 사용자가 권한이 있는지 확인하거나, 인증된 사용자인지 확인하기 위해서는 Session 또는 Token 방식을 사용해서 인가를 구현해야합니다
30+
31+
이를통해 인증이 필요한 API 에 접근을 할 때 마다 로그인을 반복하지 않고 인증 상태를 유지할 수 있습니다
32+
33+
# 1️⃣ Session 방식의 인증인가
34+
35+
## Session?
36+
37+
SessionID 를 사용해서 어떤 사용자가 서버에 로그인되어 있음이 지속되는 상태를 말합니다 <br />
38+
Session 은 서버에서 생성되며, 보통 클라이언트에 Cookie 를 통해 저장됩니다
39+
40+
## 🍪 Cookie?
41+
42+
서버가 사용자의 웹 브라우저에 전송하는 데이터로, 동일한 서버에 재요청시에 요청시 쿠키를 자동으로 함께 전송합니다.
43+
서버가 클라이언트, 웹브라우저에 정보를 저장할 때 사용합니다.
44+
45+
참고 - HTTP Cookie (https://developer.mozilla.org/ko/docs/Web/HTTP/Cookies)
46+
47+
## Session 방식의 인증인가
48+
49+
![로그인(인증)](./img/authentication-authorization/session-1.png)
50+
51+
> 사용자가 로그인 (인증) 을 요청하면...
52+
> (1) Client 가 ID , PW 를 이용해 로그인 요청을 보냅니다
53+
> (2) 서버는 DB 에서 ID , PW 를 비교해 사용자 검증을 진행합니다
54+
> (3) 올바른 사용자가 인증을 요청한 경우, Session 을 생성해 저장합니다
55+
> (4) 마지막으로 서버는 Cookie 에 SessionID 를 담아 클라이언트에 전달합니다 (HTTP Only Cookie)
56+
57+
![인증된 사용자 요청](./img/authentication-authorization/session-2.png)
58+
59+
> 이후 인증이 필요한 API 를 요청하면...
60+
> (1) 해당요청에는 자동으로 Cookie 가 함께 서버로 전송됍니다
61+
> (2) 서버는 DB 에서 Session 을 검색해서 유효한 세션인지 확인합니다 (만료되거나 조작된 세션인지 확인!)
62+
> (3) 유효한 세션인 경우 사용자 정보를 가져오고
63+
> (4) 인증이 필요한 API 에 필요한 데이터를 가져와
64+
> (5) 응답을 클라이언트에 전송합니다
65+
66+
![로그아웃](./img/authentication-authorization/session-3.png)
67+
68+
> 사용자가 로그아웃을 요청하면...
69+
> (1) 로그아웃 엔드포인트로 API 요청을 날립니다. 이때 쿠키에 세션정보가 함께 전송됩니다.
70+
> (2) 서버는 데이터베이스에서 세션정보를 검색하고 무효화합니다
71+
> (3) 서버는 클라이언트에 리다이렉션 또는 데이터를 응답합니다.
72+
73+
## Session 방식의 장단점
74+
75+
> `장점`
76+
> 세션은 Stateful, 모든 사용자의 정보를 기억하기 때문에, 기억하는 사용자의 상태를 언제든지 변경 할 수 있습니다.
77+
> 예를들어, 모바일에서 재로그인시 PC 의 세션을 무효화 시켜 로그아웃 시킬 수 있습니다
78+
> 서버에 데이터가 저장되기 때문에, 클라이언트에 사용자 정보가 노출 될 위험이 없습니다
79+
>
80+
> `단점`
81+
> 세션은 서버에서 관리되므로, 동시에 많은 사용자가 접속하면 메모리가 부족 할 수 있습니다
82+
> 서버의 복잡한 구성과 환경에서 어떤 상태를 기억하고 있어야 하므로, 확장이 어려울 수 있습니다. (Horizontal Scaling 이 어려움)
83+
> 주로 인메모리에 저장되는 세션은 서버가 예기치 못한 상황에서 종료가 되면 세션정보가 날아갈 수 있습니다.
84+
> SessionID 가 유출/탈취 되는 경우, 해당 세션으로 사용자의 정보에 접근 할 수 있습니다
85+
86+
이런 Session 방식의 단점을 극복하기 위해 Token 방식의 인증인가가 나오게 되었습니다
87+
88+
# 2️⃣ Token 방식의 인증인가
89+
90+
## JWT (JSON Web Token)
91+
92+
JWT 는 JSON 객체를 사용해 정보를 안전하게 전달하기 위한 개방형 표준 (RFC 7519) 입니다. <br />
93+
JWT 는 주로 인증과 정보 교환에 사용됩니다.
94+
95+
![JWT 구조](./img/authentication-authorization/jwt.png)
96+
97+
JWT 는 Header, Payload, Signature 세 부분으로 구성됍니다.
98+
99+
> `Header`
100+
> 헤더에는 해싱에 사용될 알고리즘과 토큰의 타입이 들어갑니다
101+
>
102+
> `Payload`
103+
> 페이로드에는 토큰에 넣을 데이터가 들어갑니다
104+
> 발급자에 대한 메타데이터, 토큰의 유효기간, 사용자 정보 등이 들어갑니다
105+
> `Signature`
106+
> Header, Payload, 비밀키를 이용해 서명값이 발급됩니다
107+
> 서버는 발급시에 사용했던 비밀키를 이용해 계산된 서명값이 일치하는지 확인합니다
108+
> 이를통해 토큰이 조작되었는지 확인 할 수 있습니다
109+
110+
## JWT 방식의 인증인가
111+
112+
![로그인(인증)](./img/authentication-authorization/jwt-1.png)
113+
114+
> 사용자가 로그인 (인증) 을 요청하면...
115+
> (1) Client 가 ID , PW 를 이용해 로그인 요청을 보냅니다
116+
> (2) 서버는 DB 에서 ID , PW 를 비교해 사용자 검증을 진행합니다
117+
> (3) 올바른 사용자가 인증을 요청한 경우, 비밀키를 이용해 JWT 토큰을 발급합니다
118+
> (4) 마지막으로 서버는 JWT 토큰을 응답으로 전송하고
119+
> (5) 클라이언트는 LocalStorage, SessionStorage, ReduxPersist 등 클라이언트측 Storage 에 저장합니다
120+
121+
![인증된 사용자 요청](./img/authentication-authorization/jwt-2.png)
122+
123+
> 이후 인증이 필요한 API 를 요청하면...
124+
> (1) 클라이언트에서 요청시, HTTP Header 의 Authorization 필드에 JWT 토큰을 삽입해 요청합니다.
125+
> (2) 서버는 해당 비밀키를 이용해 Signature 서명값이 올바른지 확인합니다
126+
> (3) JWT 를 디코딩하여 payload 의 값을 이용해 사용자를 식별하고, 해당 사용자를 기반으로 API 에 필요한 데이터를 DB로부터 불러옵니다
127+
> (4) 응답을 클라이언트에 전송합니다
128+
129+
## JWT 방식의 장단점
130+
131+
> `장점`
132+
> Signature 서명 값을 이용해 검증하고, 디코딩한 값으로 사용자 정보를 알 수 있어, 데이터베이스가 필요하지 않기 때문에 Horizontal Scaling 이 쉽다
133+
>
134+
> `단점`
135+
> JWT 토큰이 클라이언트에 저장되고, 저장된 정보는 쉽게 디코딩될 수 있기 때문에 정보 유출의 위험이 있습니다
136+
> 토큰이 탈취당하면, 토큰을 이용해 인증이 필요한 요청을 보낼 수 있습니다
137+
138+
## Access, Refresh Token 를 이용한 인증인가
139+
140+
JWT 토큰을 이용하면 토큰 탈취가 발생하는경우, 세션 방식처럼 서버측에서 무효화 할 수 없기 때문에, <br />
141+
Access Token, Refresh Token 을 이용하여 인증 인가를 구현합니다.
142+
143+
두 토큰 모두 JWT 기반의 토큰이지만, Refresh Token 은 Access Token 을 재발급 받는 용도로 사용합니다. <br />
144+
자주 사용되는 Access Token 은 유효기간을 짧게 하여 Token 이 탈취돼도 탈취자가 오래 사용하지 못하도록 방지할 수 있습니다.
145+
146+
![Access, Refresh Token](./img/authentication-authorization/jwt-access-refresh.png)
147+
148+
# CSRF (Cross-Site Request Forgery)
149+
150+
사용자의 인증정보를 탈취해 공격을 하는 CSRF 에 대해 살펴보겠습니다
151+
152+
## CSRF 공격?
153+
154+
CSRF (Cross Site Request Forgery) 는 한국어로 번역하면 사이트간 요청위조 입니다. <br />
155+
다른 사용자의 권한을 도용해, 조작된 요청을 보내는 방식으로 공격을 시도하는데, 어떻게 다른 사용자의 권한을 도용할 수 있을까요?
156+
157+
CSRF 공격이 진행되려면 다음 두 조건을 만족해야 합니다.
158+
159+
> 사용자가 `로그인한 상태`로, 원본 사이트와 유사한 `피싱 사이트에 접속`
160+
161+
이해를 돕기위해 사용자가 A 에게 송금하는 상황을 가정해보겠습니다.
162+
163+
![CSRF 공격](./img/authentication-authorization/csrf.png)
164+
165+
사용자는 로그인 되어있는 상태이기 때문에, Session ID, Token 을 탈취해 조작된 요청을 보낼 수 있습니다.
166+
167+
## CSRF 공격 방어 방법
168+
169+
### 1. Referer 검증
170+
171+
Referer 검증은 Request 를 보내는 Referer 가 일치하는지 검사하는 방법입니다. <br />
172+
Referer 헤더는 HTTP 요청의 일부로 전송되는 헤더로, 요청을 보내는 웹 페이지의 출처를 가지고 있습니다.
173+
174+
![Referer 검증](./img/authentication-authorization/csrf-defend.png)
175+
176+
Referer 헤더를 분석하여, 요청이 어디서 왔는지 확인하고, 다른 도메인에서의 요청을 제한하거나 보안을 강화할 수 있습니다.
177+
178+
### 2. CSRF 토큰
179+
180+
사용자가 로그인할 때 마다, CSRF 토큰을 생성해 세션에 저장하고, 요청시에 Form, URL Parameter, HTTP Header 와 함께 전송합니다.
181+
182+
```jsx
183+
<form>
184+
<input type="text" placeholder="송금할 계좌번호" />
185+
<input type="hidden" name="_csrf" value={CSRF_TOKEN} />
186+
</form>
187+
```
188+
189+
서버측에서는 사용자의 요청을 받을 때 마다, CSRF 토큰을 비교해 일치하는지 검사합니다.
190+
191+
CSRF 공격자는 사용자의 세션정보를 알지 못하기 때문에, CSRF 토큰을 함께 포함시키지 않으면, 올바른 요청을 보낼 수 없습니다.
192+
193+
# 😊 여담
194+
195+
브라우저 쿠키는 왜 쿠키일까...? - 헨젤과 그레텔에서 쿠키를 이용해 경로를 기억한 행위에서 유래되었다고 합니다 ㅋㅋ <br />
196+
https://cookiecontroller.com/internet-cookies/browser-cookies/
197+
198+
# 참고자료
199+
200+
- https://www.youtube.com/watch?v=UBUNrFtufWo&ab_channel=Fireship
201+
- https://www.youtube.com/watch?v=1QiOXWEbqYQ&t=620s&ab_channel=%EC%96%84%ED%8C%8D%ED%95%9C%EC%BD%94%EB%94%A9%EC%82%AC%EC%A0%84
202+
- https://www.loginradius.com/blog/engineering/guest-post/jwt-vs-sessions/
203+
- https://docs.nestjs.com/security/authentication
204+
- https://velog.io/@tosspayments/Basic-%EC%9D%B8%EC%A6%9D%EA%B3%BC-Bearer-%EC%9D%B8%EC%A6%9D%EC%9D%98-%EB%AA%A8%EB%93%A0-%EA%B2%83
205+
- https://datatracker.ietf.org/doc/html/rfc7234#section-3.2
206+
- https://developer.mozilla.org/ko/docs/Web/HTTP/Headers/Authorization
207+
- https://nordvpn.com/ko/blog/xss-attack/
208+
- https://nordvpn.com/ko/blog/csrf/
14.4 KB
Loading
24.9 KB
Loading
19.3 KB
Loading
22 KB
Loading
27.4 KB
Loading
76.1 KB
Loading
12.8 KB
Loading
14.9 KB
Loading
12.4 KB
Loading

0 commit comments

Comments
 (0)