오늘은 풀스택 개발의 핵심 중 하나인 인증 시스템 구축에 대해 이야기해볼게. 프론트엔드든 백엔드든 결국 로그인 기능을 만들게 되는데, 이때 JWTSession 같은 용어들이 막 튀어나오면서 머리가 아파지거든. 15년차 현우 선배가 실무에서 진짜 중요한 것들만 콕콕 짚어줄게.

cybersecurity authentication

1. 인증 시스템의 두 기둥: SessionJWT

인증 시스템을 설계할 때 가장 먼저 마주하는 고민이 바로 상태 유지(Stateful) 방식이냐, 무상태(Stateless) 방식이냐 하는 거야. 이게 SessionJWT를 나누는 핵심이거든.

  • Session 기반 인증 (Stateful):
    • 사용자가 로그인하면 서버는 세션 ID를 생성하고, 이 ID를 서버 메모리나 데이터베이스에 저장해.
    • 그리고 이 세션 ID를 클라이언트에게 쿠키(Cookie) 형태로 넘겨주지.
    • 클라이언트는 이후 요청마다 이 쿠키를 서버로 보내고, 서버는 쿠키의 세션 ID로 사용자 정보를 찾아 인증하는 방식이야.
    • 장점: 서버에서 세션 관리를 직접 하니 보안에 유리하고, 필요시 서버에서 강제로 세션을 만료시킬 수 있어.
    • 단점: 서버가 사용자 상태를 계속 저장해야 해서 **확장성(Scalability)**이 떨어지고, 여러 서버로 구성된 환경(로드밸런싱)에서는 세션 동기화 문제가 발생할 수 있어.
  • JWT 기반 인증 (Stateless):
    • 사용자가 로그인하면 서버는 사용자 정보를 담은 JWT (JSON Web Token)를 생성하고, 이걸 클라이언트에게 넘겨줘.
    • 이 토큰은 Header.Payload.Signature 세 부분으로 구성되는데, Payload에 사용자 ID 같은 필요한 정보가 암호화되어 담겨 있어.
    • 클라이언트는 이 토큰을 받아서 로컬 스토리지나 쿠키에 저장하고, 이후 요청마다 Authorization 헤더에 토큰을 담아 서버로 보내.
    • 서버는 토큰의 유효성(서명 확인, 만료 여부 등)만 검증하면 되기 때문에, 별도의 사용자 상태를 저장할 필요가 없어.
    • 장점: 서버가 상태를 유지하지 않아도 되니 확장성이 뛰어나고, 여러 서버 환경에서 유리해. 모바일 앱 같은 다양한 클라이언트 환경에서도 유용하고.
    • 단점: 토큰 자체가 정보를 담고 있어서 탈취당하면 위험해. 토큰 만료 전까지는 서버에서 강제로 무효화하기 어렵다는 점도 있어.

2. JWT의 실무 적용: Access TokenRefresh Token

JWT의 단점 중 하나가 토큰이 탈취당하면 위험하다는 거잖아? 그래서 실무에서는 보통 두 가지 토큰을 함께 사용해.

  • Access Token: 주로 짧은 유효 기간(예: 30분~1시간)을 가진 토큰이야. 실제 API 요청 시 인증에 사용되지. 만료되면 재인증해야 해.
  • Refresh Token: Access Token보다 훨씬 긴 유효 기간(예: 1주~1개월)을 가진 토큰이야. Access Token이 만료되었을 때, 이 Refresh Token을 사용해서 새로운 Access Token을 발급받는 데 사용돼.

💡 현우 선배의 꿀팁! Access Token은 탈취 시 피해를 줄이기 위해 짧게, Refresh Token은 보안을 강화하기 위해 HttpOnly 쿠키에 저장해서 XSS 공격으로부터 보호하는 게 일반적인 패턴이야. 물론 Refresh Token도 탈취당하면 위험하니, 적절한 만료 기간과 보안 대책이 필요해.

software development workspace

3. 더 큰 그림: OAuth 2.0OpenID Connect

JWTSession은 '어떻게 인증 상태를 관리할 것인가'에 대한 기술적인 선택이라면, OAuth 2.0OpenID Connect (OIDC)는 '어떻게 사용자에게 인증/인가를 제공할 것인가'에 대한 프레임워크프로토콜에 가까워.

  • OAuth 2.0: 이건 인증이라기보다는 인가(Authorization) 프레임워크야. "너의 구글 계정 정보를 우리 서비스가 사용할 수 있도록 허락해줄래?" 같은 상황에 쓰이지. 사용자의 자원에 직접 접근하지 않고, 권한을 위임받는 방식이야. Access Token을 주고받는다는 점에서 JWT와 연결되기도 해.
  • OpenID Connect (OIDC): OAuth 2.0 위에 인증(Authentication) 기능을 추가한 거야. "너 누구니?"를 물어보고, 사용자 신원 정보를 ID Token (이것도 JWT 형식이야)으로 제공해주는 표준이지. 구글, 카카오 같은 소셜 로그인 기능이 바로 이 OIDC를 활용하는 대표적인 예시야.

4. 실무에서 보안 고려사항

인증 시스템은 보안이 최우선이거든. 몇 가지 중요한 점들을 잊지 마.

  • HTTPS 사용: 모든 통신은 반드시 HTTPS를 통해 암호화되어야 해. 평문 통신은 절대 금지!
  • 쿠키 보안: HttpOnly, Secure, SameSite 플래그를 꼭 사용해서 쿠키 탈취와 CSRF 공격을 방지해야 해.
  • 토큰 만료 관리: Access Token은 짧게, Refresh Token은 길게 가져가되, Refresh Token도 탈취 시 대책(예: 사용된 Refresh Token 블랙리스트 관리)을 마련해야 해.
  • 비밀번호 해싱: 사용자 비밀번호는 절대 평문으로 저장하면 안 돼. Bcrypt, Scrypt 같은 강력한 해싱 알고리즘을 사용해서 저장해야 한다.

💡 핵심 정리

  • Session은 서버가 상태를 관리하는 Stateful 방식, JWT는 클라이언트가 토큰을 관리하는 Stateless 방식이야.
  • JWT의 보안 취약점을 보완하기 위해 Access TokenRefresh Token을 함께 사용하는 것이 일반적이야.
  • OAuth 2.0인가 프레임워크, OpenID ConnectOAuth 2.0 위에 인증 기능을 추가한 표준이야.
  • 인증 시스템 구축 시 HTTPS, 안전한 쿠키 설정, 토큰 만료 관리, 비밀번호 해싱 등 보안에 각별히 신경 써야 해. 인증 시스템은 서비스의 근간이 되는 중요한 부분이니, 각 방식의 장단점을 명확히 이해하고 프로젝트의 요구사항에 맞춰 신중하게 선택하는 게 중요해. 처음에는 복잡하게 느껴질 수 있지만, 몇 번 구현해보면 감이 잡힐 거야. 힘내서 멋진 시스템 만들어보자!