API 설계 시 처음 가졌던 고민
처음 API를 설계할 때, 유저의 정보(User ID)를 프론트엔드에 넘겨주는 것은 보안적으로 위험할 수 있다고 판단했다.
그래서 프론트엔드에서는 유저 정보를 받지 않고, 백엔드에서 토큰을 이용해 본인 여부를 확인하고 필요한 결과만 반환하는 방식으로 설계했다.
예를 들어, 게시글 수정이나 삭제 시, 유저가 해당 게시글의 작성자인지 확인하는 로직은 프론트엔드가 아닌 백엔드에서 처리하도록 했다.
이렇게 하면 프론트엔드 측에서 유저 정보를 직접 다루지 않기 때문에 보안적으로 더 안전하다고 생각했기 때문이다.
회원가입 API를 설계하며 발견한 코드와 RESTful 원칙
회원가입 API를 구현하던 중, 여러 자료를 찾아보고 깃허브 프로젝트 레포를 보다가 다음과 같은 코드를 발견했다.
@PostMapping("/sign-up")
public ResponseEntity<Void> signup(@Valid @RequestBody MemberSignUpRequest request) {
return ResponseEntity.created(URI.create("/members/" + memberService.signup(request))).build();
}
이 코드는 회원가입이 완료된 후 생성된 User ID를 포함한 URI를 프론트엔드로 반환하고 있었다.
처음에는 왜 User ID를 프론트엔드에 넘겨줄까? 하는 의문이 들었지만, 찾아보니 RESTful 설계 원칙에 따르면 이렇게 자원의 경로를 명시적으로 보여주는 것이 권장되는 방식이라는 것을 알게 되었다.
RESTful 설계 원칙이란?
REST(Representational State Transfer)는 웹 서비스 설계에서 자주 사용되는 아키텍처 스타일이다.
RESTful 설계 원칙의 핵심 개념
- URI(Uniform Resource Identifier)를 통해 자원(Resource)을 명시한다.
- HTTP Method(POST, GET, PUT, DELETE, PATCH)를 사용하여 자원에 대해 CRUD 작업을 수행한다.
예를 들어, 회원가입 후 생성된 유저 정보를 반환할 때는 다음과 같이 URI를 명시적으로 생성한다.
POST /sign-up → 201 Created (Location: /members/{userId})
RESTful 설계 원칙을 따를 때의 장점
- 가독성: API의 경로를 보면 어떤 자원에 대한 작업인지 바로 이해할 수 있다.
- 직관성: 응답으로 받은 URI를 통해 사용자가 어떤 리소스가 생성되었는지 명확히 알 수 있다.
- 표준화: RESTful 설계 원칙은 많은 개발자와 프로젝트에서 사용되기 때문에, 코드의 일관성과 유지보수성이 높아진다.
고민: User ID를 넘겨주는 것이 보안적으로 문제가 될까?
RESTful 설계 원칙을 이해하고 나니, User ID를 프론트엔드로 넘겨주는 것이 가독성과 직관성 면에서 더 나은 설계라는 생각이 들었다.
하지만 처음 API를 설계할 때는 User ID를 프론트엔드로 넘겨주는 것이 보안적으로 위험하다고 생각했기 때문에 망설여졌다.
그렇게 여기서 하나의 의문이 들었는데, 정말 내 생각처럼 User ID를 넘겨주는 것이 보안적으로 위험할까? 이다. 만약 위험하지 않다면 가독성과 직관성을 잡을 수 있는 RESTful 설계 원칙을 사용하지 않을 이유가 없었다.
❓ 의문: 클라이언트 측에서 User ID를 안다고 보안 위협이 될까?
결론: User ID를 넘겨줘도 보안적으로 큰 위협이 되지 않는다
User ID는 공공 데이터로 간주해도 괜찮다!
User ID는 비밀번호와 같은 민감한 정보가 아니다. User ID는 특정 사용자와 연관된 고유 식별자일 뿐이며, 이를 안다고 해서 그 유저의 권한을 탈취하거나 악의적인 행위를 할 수 있는 것은 아니다.
예를 들어, 깃허브나 블로그 플랫폼에서도 사용자의 고유 ID(User ID)가 URL에 포함되며, 누구나 접근할 수 있는 형태로 제공된다.
https://github.com/username
https://medium.com/@username
이를 통해 User ID는 공공 데이터로 간주해도 무방하며, 이를 노출한다고 해서 보안에 직접적인 위협이 되는 것은 아니라고 판단했다.
🚨 보안적으로 중요한 것은 세션 토큰과 민감한 정보
세션 토큰: 사용자의 인증 상태를 나타내는 중요한 정보로, 반드시 안전하게 관리되어야 합니다.비밀번호와 같은 민감한 정보는 절대 노출되어서는 안된다.
결국, User ID는 보안 위협이 되지 않기 때문에 RESTful 설계 원칙을 적용하여 더 가독성 있는 API를 만드는 것이 바람직하다고 결론을 내렸다.
최종 API 설계 변경
기존의 API 응답 방식:
POST /signup → 201 Created
RESTful 설계 원칙을 적용한 방식:
POST /signup → 201 Created (Location: /members/{userId})
회원가입이 성공하면, 생성된 User ID를 포함한 URI를 Location 헤더에 반환하여 프론트엔드에서 해당 자원에 바로 접근할 수 있도록 개발했다.