🔐 JWT만 알면 끝? 실무 인증 방식 완벽 가이드
"회원가입이랑 로그인 구현하려면 JWT만 공부하면 되죠?"
아니요! 🙅♂️
실무에서는 서비스 성격에 따라 다양한 인증 방식을 사용합니다.
이 글에서는 전통적인 방식부터 최신 트렌드까지, 실무에서 바로 적용할 수 있는 인증 방식들을 소개합니다.
📋 목차
Session 기반 인증
🔐 동작 방식
로그인 성공 → 서버가 세션(Session) 생성
→ 클라이언트는 세션 ID 쿠키만 보냄
→ 서버가 상태(state)를 관리
✅ 장점
- ✔️ 구현 쉬움 - 가장 직관적인 방식
- ✔️ 보안 직관적 - 서버에서 모든 것을 제어
- ✔️ Spring Security와 궁합 좋음
❌ 단점
- ❗ 서버 확장(scale-out) 어려움
- ❗ Redis 같은 세션 스토어 필요
🎯 추천 상황
- SSR 웹 애플리케이션
- 관리자 페이지
- 트래픽이 크지 않은 서비스
💻 코드 예시
로그인 컨트롤러
@PostMapping("/login")
public String login(HttpServletRequest request) {
HttpSession session = request.getSession(true);
session.setAttribute("USER_ID", 1L);
return "redirect:/";
}
인증 체크
@GetMapping("/mypage")
public String myPage(HttpSession session) {
if (session.getAttribute("USER_ID") == null) {
return "redirect:/login";
}
return "mypage";
}
💡 Tip: 서버가 상태(Session)를 관리하므로 SSR/관리자 페이지에 최적입니다.
OAuth 2.0 / Social Login
🔐 동작 방식
Google / Kakao / GitHub 로그인
→ 토큰 기반 인증
→ 외부 서비스가 사용자 정보 제공
✅ 장점
- ✔️ 회원가입 허들 ↓ - 클릭 한 번으로 가입
- ✔️ 비밀번호 직접 관리 안 해도 됨
- ✔️ 보안 책임 일부 외부 위임
❌ 단점
- ❗ 외부 서비스 의존
- ❗ 커스터마이징 제한
🎯 추천 상황
- B2C 서비스
- 초기 스타트업
- 빠른 MVP 개발
💻 코드 예시
의존성 추가
implementation 'org.springframework.boot:spring-boot-starter-oauth2-client'
application.yml 설정
spring:
security:
oauth2:
client:
registration:
google:
client-id: xxx
client-secret: xxx
Security 설정
http
.oauth2Login()
.defaultSuccessUrl("/");
💡 Tip: 비밀번호 직접 관리가 필요 없어 MVP에 최강자입니다!
Cookie 기반 Token 인증
🔐 동작 방식
Access Token을 HttpOnly Cookie에 저장
→ JavaScript에서 접근 불가
→ XSS 공격 방어
⚠️ 주의: "JWT를 안 쓴다"가 아니라 JWT를 안전하게 숨기는 방식입니다!
✅ 장점
- ✔️ XSS 공격 방어 - JS로 토큰 접근 불가
- ✔️ 브라우저 친화적
❌ 단점
- ❗ CSRF 방어 필요
🎯 추천 상황
- 웹 서비스
- JWT는 쓰되 보안을 강화하고 싶을 때
💻 코드 예시
로그인 시 쿠키 저장
ResponseCookie cookie = ResponseCookie.from("access_token", token)
.httpOnly(true)
.secure(true)
.path("/")
.maxAge(3600)
.build();
response.addHeader("Set-Cookie", cookie.toString());
필터에서 쿠키 읽기
Cookie[] cookies = request.getCookies();
for (Cookie c : cookies) {
if ("access_token".equals(c.getName())) {
String token = c.getValue();
// 토큰 검증 로직
}
}
💡 Tip: 웹 쇼핑몰 개발 시 매우 추천하는 방식입니다!
API Key 인증
🔐 동작 방식
요청 헤더에 API Key 포함
→ 서버에서 Key 검증
→ 서버 간 통신에 사용
✅ 장점
- ✔️ 단순함 - 구현이 매우 간단
- ✔️ 서버-서버 통신에 최적
❌ 단점
- ❗ 사용자 로그인에는 부적합
🎯 추천 상황
- 내부 API
- 백오피스 연동
- 파트너 API
💻 코드 예시
요청 헤더
X-API-KEY: abc123
필터 구현
String apiKey = request.getHeader("X-API-KEY");
if (!"abc123".equals(apiKey)) {
response.setStatus(HttpStatus.UNAUTHORIZED.value());
return;
}
⚠️ 주의: 사용자 로그인용이 아닌 서버–서버 통신 전용입니다!
SSO (Single Sign-On)
🔐 동작 방식
한 번 로그인
→ 여러 서비스 이용 가능
→ OAuth2 + Token 조합 활용
✅ 장점
- ✔️ 대규모 서비스에 적합
- ✔️ 사용자 경험 최고 - 한 번의 로그인으로 모든 서비스 이용
❌ 단점
- ❗ 구현 복잡
- ❗ 인프라 필요
🎯 추천 상황
- 여러 서비스를 운영하는 경우
- 기업/플랫폼 서비스
💡 실제 사례: Google 계정으로 YouTube, Gmail, Google Drive를 모두 사용하는 것이 SSO입니다!
Magic Link
🔐 동작 방식
이메일로 로그인 링크 발송
→ 링크 클릭
→ 인증 완료
✅ 장점
- ✔️ 비밀번호 관리 불필요 ❌
- ✔️ UX 좋음 - 간편한 로그인 경험
❌ 단점
- ❗ 이메일 의존
- ❗ 피싱 주의 필요
🎯 추천 상황
- SaaS 서비스
- 간단한 서비스
- 내부 툴
💻 코드 예시
토큰 생성
String token = UUID.randomUUID().toString();
redisTemplate.opsForValue().set(token, userId, 10, TimeUnit.MINUTES);
이메일 링크
https://example.com/auth/magic?token=xxxx
인증 처리
@GetMapping("/auth/magic")
public String magicLogin(@RequestParam String token, HttpSession session) {
Long userId = redisTemplate.opsForValue().get(token);
session.setAttribute("USER_ID", userId);
return "redirect:/";
}
💡 Tip: Notion, Slack 등 많은 SaaS 서비스에서 이 방식을 채택하고 있습니다!
한눈에 비교
📊 비교표
| 방식 | 서버 상태 | 보안 수준 | 구현 난이도 | 추천 상황 |
|---|---|---|---|---|
| Session | Stateful | ⭐⭐⭐⭐ | ⭐ | 웹/관리자 |
| JWT (Header) | Stateless | ⭐⭐⭐ | ⭐⭐ | 모바일/API |
| JWT + Cookie | Stateless | ⭐⭐⭐⭐⭐ | ⭐⭐ | 웹 쇼핑몰 |
| OAuth2 | Stateless | ⭐⭐⭐⭐ | ⭐⭐⭐ | B2C |
| Magic Link | Stateless | ⭐⭐⭐ | ⭐⭐ | SaaS |
| API Key | Stateless | ⭐⭐ | ⭐ | 서버 통신 |
🎯 당신에게 딱 맞는 방식은?
웹 쇼핑몰 개발 중이라면?
👉 Session 기반 또는 JWT + HttpOnly Cookie
- 보안이 중요한 결제 정보를 다루므로 안전성이 최우선
- 브라우저 기반이므로 쿠키 활용이 유리
모바일 앱 / API 서버 개발 중이라면?
👉 JWT (Authorization Header)
- Stateless 구조로 서버 확장에 유리
- 모바일 환경에서 토큰 관리가 용이
빠른 MVP를 만들어야 한다면?
👉 OAuth2 + 자체 계정 병행
- 초기 사용자 확보가 쉬움
- 나중에 자체 인증 시스템 추가 가능
💡 마무리
인증 방식에는 정답이 없습니다.
서비스의 특성, 보안 요구사항, 개발 리소스 등을 종합적으로 고려해서 선택해야 합니다.
체크리스트 ✅
- 우리 서비스의 주 사용자는 누구인가? (웹/모바일)
- 서버 확장 계획이 있는가?
- 보안 수준은 어느 정도 필요한가?
- 개발 기간은 얼마나 있는가?
- 외부 서비스 의존도를 얼마나 허용할 수 있는가?
이 질문들에 대한 답이 명확해지면, 자연스럽게 어떤 인증 방식을 선택해야 할지 보일 것입니다! 🚀