FrontEnd Develop

⏿실제 백엔드와 프론트엔드 통신 #1. 인증과 권한부여 <토큰>

Frisbeen 2025. 1. 24. 19:48

토큰은 클라이언트와 서버 사이에서 인증을 담당하는 열쇠와 같은 존재입니다. 이번 포스팅에서는 토큰이란 무엇인지, 왜 필요한지, 그리고 어떻게 사용하는지 알아보겠습니다.

 

 

# 토큰은 뭐고 왜 가져와야하는가?

const accessToken = localStorage.getItem('token');
const refreshToken = localStorage.getItem('refreshToken');

 

먼저 토큰은 서버와 클라이언트(사용자) 간의 인증 및 권한 부여를 위해 사용되는 데이터 조각입니다.

클라이언트가 서버에 접근할때, 클라이언트의 요청이 인증된 요청인지 아닌지 확인하는 디지털 증명서입니다.

 

일반적으로 두 종류의 토큰이 있습니다.

 Access Token (엑세스 토큰): 주로 인증 및 권한 부여를 위해 서버에 보내는 짧은 수명의 토큰.

 Refresh Token (리프레시 토큰): 엑세스 토큰이 만료되었을 때 새로운 엑세스 토큰을 발급받기 위한 비교적 긴 수명의 토큰.

 

즉 리프레시 토큰은 엑세스 토큰을 위한 토큰입니다.

 

# 서버에는 왜 보내야하는가?

1.  서버가 클라이언트의 신원을 확인하기 위해

 클라이언트(사용자)가 로그인 후 서버로 요청을 보낼 때, 서버는 요청을 보낸 주체가 누구인지 알 수 없습니다.

 엑세스 토큰을 통해 요청의 주체(사용자)가 누구인지 식별할 수 있습니다.

 예:

 토큰에는 사용자 ID, 권한, 토큰의 만료 시간 등이 포함됩니다.

 서버는 요청을 받은 후, 토큰을 확인해 사용자가 요청을 보낼 권한이 있는지 확인합니다.

 

 

2 보안을 위해 비밀번호를 대신 사용

 토큰은 사용자의 비밀번호를 대신하여 인증에 사용됩니다.

 사용자가 서버에 요청을 보낼 때마다 비밀번호를 보내는 것은 보안상 위험(예: 도청, 중간자 공격)이 크기 때문에, 한 번 로그인한 후 비밀번호 대신 토큰을 사용하여 인증을 처리합니다.

 

 

 

3 무상태성 유지 (Stateless Architecture)

 토큰을 사용하면 서버가 클라이언트의 세션을 별도로 저장하지 않아도 됩니다.

 요청마다 클라이언트가 토큰을 제공하면, 서버는 토큰을 검증하여 해당 사용자의 신원을 확인할 수 있습니다.

 이 방식은 서버 확장성과 효율성을 높입니다.

 

 

예를 들어, 쇼핑몰 웹사이트가 여러 서버를 사용한다고 가정할 때, 서버는 클라이언트의 세션을 저장하지 않으므로 확장성이 높아집니다. 클라이언트는 요청마다 토큰을 보내기 때문에 어떤 서버에 요청이 도달하더라도 인증을 동일하게 처리할 수 있습니다.”

 

 

 

2. localStorage.getItem('token') & localStorage.getItem('refreshToken')

 accessToken: 사용자의 인증 상태를 나타내는 엑세스 토큰을 가져옵니다.

 refreshToken: 엑세스 토큰이 만료되었을 때 새 엑세스 토큰을 발급받는 데 사용하는 리프레시 토큰을 가져옵니다.

 

이 두 값은 localStorage에 저장된 값을 읽어오며, 이를 요청 헤더에 추가하여 백엔드에 전송합니다.

 

 

그러나 로컬스토로지의 단점이 있는데... 

“로컬 스토리지에 저장하면 XSS(교차 사이트 스크립팅) 공격에 취약해질 수 있습니다. 이는 악성 스크립트를 통해 저장된 토큰이 탈취될 위험이 있음을 의미합니다. 안전성을 위해 리프레시 토큰은 HttpOnly 쿠키에 저장하는 것도 고려할 수 있습니다.”

 

 

토큰의 동작 원리

 

1. 로그인 시 토큰 발급

1. 사용자가 ID와 비밀번호를 입력해 로그인 요청을 보냅니다.

2. 서버는 ID와 비밀번호를 확인한 후, 엑세스 토큰 리프레시 토큰을 클라이언트에게 발급합니다.

 

한번 더 강조합니다.

 

 엑세스 토큰: 짧은 기간 동안 유효한 인증 수단.

 리프레시 토큰: 엑세스 토큰이 만료되었을 때, 새 엑세스 토큰을 발급받기 위해 사용.

 

2.  클라이언트가 서버에 요청

클라이언트는 API 요청을 보낼때 요청 헤더에 엑세스 토큰을 포함하여 서버에 던집니다.

 

그리고 서버는 토큰을 확인한 후, 요청을 보낸 사용자가 누구인지 확인하고 요청에 권한이 있는 체크합니다.

 

인증된다면 서버는 요청에 맞는 데이터를 응답합니다.

 

3. 엑세스 토큰은 휘발성이다.

맞습니다. 따라서 엑세스 토큰이 만료되면, 클라이언트는 리프레시 토큰을 활용해서 새로운 엑세스 토큰을 발급해줍니다.

이 방식은 엑세스 토큰이 도난당해도 어차피 휘발성이기에 보안성을 높입니다.

 

 

결론

 토큰은 클라이언트가 서버에 요청을 보낼 때 자신의 신원을 증명하기 위한 수단입니다.

토큰은 비밀번호 대신 사용되어 보안을 강화하고, 서버의 상태를 유지하지 않는 무상태 아키텍처를 가능하게 합니다.

서버는 토큰을 검증하여 요청을 보낸 사용자가 인증된 사용자인지 확인하며, 요청이 유효한 경우에만 데이터를 제공합니다.

 

“따라서 토큰은 백엔드와 프론트엔드가 안전하게 통신하고 사용자의 데이터를 보호하기 위한 핵심 요소입니다. 하지만, 이를 안전하게 관리하지 않으면 보안 위협에 노출될 수 있으니, 저장 위치와 사용 방식에 주의해야 합니다.”