Develop/Network

[Network] 사용자 인증 및 시크릿 키 발급(Token, SecretKey)

DevPi 2024. 8. 24. 16:31
반응형

오늘은 Spring Boot 기반 애플리케이션에서 사용자 인증과 토큰 발급 과정, 그리고 시크릿 키 관리 절차를 UI, Back End, DB 구조를 중심으로 살펴보겠습니다. 이 글에서는 실제로 애플리케이션이 어떻게 사용자 인증을 처리하고, 안전하게 토큰과 시크릿 키를 발급 및 관리하는지에 대해 다룹니다.


1.  사용자 인증 요청 (UI -> Back End)

먼저, 사용자는 애플리케이션의 UI에서 로그인 시도합니다. 이 과정은 주로 로그인 페이지에서 사용자 이름과 비밀번호를 입력하는 것으로 시작됩니다.

 

클라이언트 측에서의 요청

사용자가 로그인 폼에 정보를 입력하고 "로그인" 버튼을 클릭하면, 이 정보가 백엔드 서버로 전송됩니다. 일반적으로 이 과정은 HTTPS를 통해 보안이 유지되며, REST API의 POST 요청 형태로 이루어집니다.

POST /api/auth/login
{
  "username": "user123",
  "password": "securepassword"
}

이 요청은 사용자 인증 과정의 첫 번째 단계로, 입력된 자격 증명이 올바른지 백엔드에서 검증합니다.


2.  사용자 자격 증명 확인 (Back End -> DB)

서버는 사용자 자격 증명이 유효한지 확인하기 위해 데이터베이스와 통신합니다. 이 단계에서는 주로 사용자의 비밀번호를 검증하는 과정이 포함됩니다.

 

DB 조회 및 비밀번호 검증

백엔드는 데이터베이스에서 사용자 정보를 조회한 후, 입력된 비밀번호를 해시화하여 데이터베이스에 저장된 해시된 비밀번호와 비교합니다.

SELECT * FROM users WHERE username = 'user123';

비밀번호가 일치하면 인증이 성공한 것입니다. 반대로, 일치하지 않거나 사용자가 존재하지 않으면 인증이 실패합니다. 인증 실패 시, 백엔드는 클라이언트에 적절한 오류 메시지를 반환합니다.


3.  토큰 및 시크릿 키 생성 (Back End)

인증이 성공하면, 백엔드는 사용자에게 세션을 관리할 수 있는 토큰(JWT 등)과 필요한 경우 시크릿 키를 생성합니다. 이 토큰과 시크릿 키는 이후의 요청에서 사용자의 신원을 확인하는 데 사용됩니다.

 

JWT 토큰 생성

JWT(JSON Web Token)는 사용자 정보를 포함하는 토큰입니다. 서버는 사용자 ID, 역할 등 필요한 정보를 JWT의 페이로드에 포함하고, 비밀 키로 서명하여 토큰을 생성합니다.

String token = Jwts.builder()
            .setSubject(userId)
            .setIssuedAt(new Date())
            .setExpiration(new Date(System.currentTimeMillis() + 86400000)) // 24시간 유효
            .signWith(SignatureAlgorithm.HS256, secretKey)
            .compact();

 

시크릿 키 발급

특정 작업에서 사용자가 개인화된 시크릿 키를 필요로 한다면, 서버는 이 시점에서 고유한 시크릿 키를 생성하여 데이터베이스에 저장하고, 클라이언트에 반환할 수 있습니다.

UPDATE users SET secret_key = 'generatedSecretKey' WHERE id = 'user123';

4.  토큰 및 시크릿 키 저장 및 반환 (Back End -> UI, DB)

서버는 생성된 토큰과 시크릿 키를 클라이언트에 반환하고, 이를 데이터베이스에 저장하여 이후 검증 및 세션 관리에 활용합니다.

 

클라이언트 측에서의 처리

클라이언트는 서버로부터 받은 토큰을 안전한 장소(예: localStorage 또는 sessionStorage)에 저장합니다. 이후 API 요청을 보낼 때 이 토큰을 사용하여 인증된 상태를 유지합니다.

{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "secretKey": "generatedSecretKey"
}

5.  클라이언트의 토큰 사용 (UI)

사용자가 애플리케이션 내에서 보호된 리소스에 접근하려고 할 때, 클라이언트는 저장된 토큰을 HTTP 요청의 Authorization 헤더에 포함시켜 서버로 전송합니다.

GET /api/protected/resource
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

이 과정을 통해 서버는 사용자의 신원을 확인하고, 보호된 리소스에 대한 접근을 허용합니다.


6.  토큰 검증 및 리소스 제공 (Back End -> DB)

백엔드는 클라이언트로부터 받은 토큰의 유효성을 검증한 후, 사용자가 요청한 리소스에 접근할 수 있도록 허용합니다.

 

토큰 검증

서버는 토큰의 서명을 확인하고, 만료 여부 및 페이로드에 포함된 정보를 검증합니다.

Claims claims = Jwts.parser()
            .setSigningKey(secretKey)
            .parseClaimsJws(token)
            .getBody();

 

리소스 제공

토큰이 유효하다면, 서버는 요청한 리소스를 클라이언트에게 제공합니다.


요약

이와 같은 절차를 통해, 클라이언트와 서버는 안전하게 통신하며, 사용자는 보호된 리소스에 접근할 수 있습니다. 이 과정에서 중요한 것은 모든 단계에서 데이터의 무결성과 보안을 유지하는 것입니다. 토큰과 시크릿 키는 이러한 보안을 유지하는 핵심 요소로, 올바르게 관리되어야 합니다.

반응형