728x90
1. 도입: 왜 인증과 인가를 구분해야 할까?
현대 웹 애플리케이션은 사용자와 끊임없이 소통합니다.
그러나 “너 누구냐?”, “너 이거 해도 돼?” 같은 질문을 기술적으로 처리하기 위해선
바로 **인증(Authentication)**과 인가(Authorization) 개념이 필요합니다.
많은 개발자들이 이 둘을 헷갈리거나, 세션/토큰을 단순히 기술적인 수단으로만 인식하곤 합니다.
이번 글에서는 세션(Session), JWT, OAuth2가 각각 어떤 역할을 하고 어떻게 다른지 구체적으로 설명합니다.
예를 들어, 당신이 회사 사무실에 출입한다고 가정해 봅시다.
**출입증을 보여주는 행위가 '인증', 회의실에 들어갈 수 있는 권한 여부는 '인가'**입니다.
1.1 인증과 인가
항목 | 인증 (Authentication) | 인가 (Authorization) |
목적 | 누구인지 확인 | 권한 여부 확인 |
시점 | 로그인 시점 | 요청 처리 시점 |
예시 | 로그인 성공 | 게시글 수정 권한 확인 |
기술 | 세션, JWT, OAuth2 로그인 등 | 역할 기반 권한 관리 (RBAC), 접근제어 |
인증은 “신원 확인”,
인가는 “권한 확인”입니다.
1.2 세션(Session) 기반 인증
✅ 특징
- 서버가 사용자의 로그인 상태를 기억
- 사용자의 브라우저에는 세션 ID가 쿠키로 저장됨
- 서버에는 세션 ID와 매핑되는 사용자 정보를 보관
장점 | 단점 |
구현이 쉽고 전통적인 방식 | 서버에 상태(세션 데이터)를 저장해야 함 |
HTTPOnly 쿠키 활용으로 보안 강화 가능 | 분산 환경에서 확장 어려움 (세션 클러스터링 필요) |
3. JWT 기반 인증
✅ 특징
- 로그인 성공 시 서버가 JSON Web Token을 생성
- 서버는 상태를 저장하지 않고, 클라이언트가 토큰을 보관
- 각 요청 시 토큰을 HTTP Header에 담아 전송
장점 | 단점 |
서버에 상태를 저장하지 않아 확장성 높음 | 탈취 시 위조된 사용자로 행동 가능 (만료 전까지) |
다양한 클라이언트 환경에서 활용 가능 | 토큰 만료 처리, 키 관리 등 보안 고려 필요 |
✅ 스프링부트 예시 (JWT 생성)
String jwt = Jwts.builder()
.setSubject("admin")
.setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1시간
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
4. OAuth2 인증
✅ 특징
- 사용자가 제3자 서비스(Google, Kakao 등)를 통해 로그인
- 클라이언트는 Access Token을 받아 서비스 접근
- 주로 소셜 로그인, 외부 인증 연동에 사용
장점 | 단잠 |
로그인 기능을 외부에 위임 가능 | 초기 구현 복잡 |
소셜 로그인, 연동 서비스에 적합 | 보안 구성에 대한 이해 필요 |
✅ 스프링부트 설정 요약(yaml)
spring:
security:
oauth2:
client:
registration:
google:
client-id: [your-client-id]
client-secret: [your-secret]
scope: profile, email
스프링 시큐리티의 OAuth2 클라이언트 기능을 통해
구글/네이버/카카오 로그인을 쉽게 구현할 수 있습니다.
2. 개념 정리 및 비교
2.1 인증(Authentication)이란?
- 사용자가 누구인지 확인하는 절차입니다.
- 주로 ID/PW, 토큰, OAuth, 생체 인식 등으로 신원을 확인합니다.
- 인증은 로그인과 같은 사용자 식별 행위입니다.
"너는 누구냐?"
→ 인증은 그 질문에 대한 대답입니다.
2.1.2 세션(Session) 기반 인증
✅ 특징
- 서버가 사용자의 로그인 상태를 기억
- 사용자의 브라우저에는 세션 ID가 쿠키로 저장됨
- 서버에는 세션 ID와 매핑되는 사용자 정보를 보관
장점 | 단점 |
구현이 쉽고 전통적인 방식 | 서버에 상태(세션 데이터)를 저장해야 함 |
HTTPOnly 쿠키 활용으로 보안 강화 가능 | 분산 환경에서 확장 어려움 (세션 클러스터링 필요) |
2.1.3 JWT 기반 인증
✅ 특징
- 로그인 성공 시 서버가 JSON Web Token을 생성
- 서버는 상태를 저장하지 않고, 클라이언트가 토큰을 보관
- 각 요청 시 토큰을 HTTP Header에 담아 전송
장점 | 단점 |
서버에 상태를 저장하지 않아 확장성 높음 | 탈취 시 위조된 사용자로 행동 가능 (만료 전까지) |
다양한 클라이언트 환경에서 활용 가능 | 토큰 만료 처리, 키 관리 등 보안 고려 필요 |
✅ 스프링부트 예시 (JWT 생성)
String jwt = Jwts.builder()
.setSubject("admin")
.setExpiration(new Date(System.currentTimeMillis() + 3600000)) // 1시간
.signWith(SignatureAlgorithm.HS256, secretKey)
.compact();
2.1.4 OAuth2 인증
✅ 특징
- 사용자가 제3자 서비스(Google, Kakao 등)를 통해 로그인
- 클라이언트는 Access Token을 받아 서비스 접근
- 주로 소셜 로그인, 외부 인증 연동에 사용
장점 | 단잠 |
로그인 기능을 외부에 위임 가능 | 초기 구현 복잡 |
소셜 로그인, 연동 서비스에 적합 | 보안 구성에 대한 이해 필요 |
✅ 스프링부트 설정 요약(yaml)
spring:
security:
oauth2:
client:
registration:
google:
client-id: [your-client-id]
client-secret: [your-secret]
scope: profile, email
스프링 시큐리티의 OAuth2 클라이언트 기능을 통해
구글/네이버/카카오 로그인을 쉽게 구현할 수 있습니다.
2.2 인가(Authorization)란?
- 인증된 사용자가 특정 리소스에 접근 가능한 권한이 있는지를 검증하는 과정입니다.
- 예: 일반 유저가 관리자 페이지에 접근하지 못하도록 제어
"너에게 이 페이지를 볼 권한이 있느냐?"
→ 인가는 그 질문에 대한 대답입니다.
2.3 기술별 종합 비교
구분 | 세션 | JWT | OAuth2 |
서버 상태 저장 | 필요함 | 필요 없음 | 필요 없음 |
확장성 | 낮음 | 높음 | 높음 |
사용 예 | 일반 웹 로그인 | REST API 인증 | 소셜 로그인, 연동 서비스 |
주요 특징 | 서버 쿠키 관리 | 토큰 자체에 정보 포함 | 인증 서버 위임 |
3. 실전 코드: Java 11 + Spring Boot 환경
3.1 인증 구현 예제 (Spring Security + JWT)
📁 SecurityConfig.java
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/login", "/public/**").permitAll()
.anyRequest().authenticated()
.and()
.addFilter(new JwtAuthenticationFilter(authenticationManager()));
}
}
📁 JwtAuthenticationFilter.java
public class JwtAuthenticationFilter extends UsernamePasswordAuthenticationFilter {
private AuthenticationManager authenticationManager;
public JwtAuthenticationFilter(AuthenticationManager authenticationManager) {
this.authenticationManager = authenticationManager;
setFilterProcessesUrl("/login"); // 로그인 경로
}
@Override
public Authentication attemptAuthentication(HttpServletRequest request,
HttpServletResponse response) {
try {
LoginRequest loginRequest = new ObjectMapper()
.readValue(request.getInputStream(), LoginRequest.class);
return authenticationManager.authenticate(
new UsernamePasswordAuthenticationToken(
loginRequest.getUsername(),
loginRequest.getPassword()
)
);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
3.2 인가 구현 예제 (@PreAuthorize)
📁 UserController.java
@RestController
@RequestMapping("/admin")
public class AdminController {
@PreAuthorize("hasRole('ADMIN')")
@GetMapping("/dashboard")
public String getAdminDashboard() {
return "관리자 전용 대시보드입니다.";
}
}
📁 UserDetailsService 커스터마이징
public class CustomUserDetails implements UserDetails {
private final User user;
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return Collections.singleton(new SimpleGrantedAuthority("ROLE_" + user.getRole()));
}
// 생략: getUsername(), getPassword(), isEnabled() 등 구현
}
4. 인증과 인가 설계 시 고려사항
항목 | 인증 (Authentication) | 인가 (Authorization) |
목적 | 사용자 확인 | 리소스 접근 권한 확인 |
시점 | 로그인 시점 | 리소스 요청 시점 |
예시 | 로그인 | 게시글 수정, 관리자 페이지 접근 |
기술 | JWT, OAuth2, ID/PW | RBAC, ACL, @Secured, @PreAuthorize |
구현 위치 | 로그인 필터, AuthenticationProvider | Security Filter Chain, Controller 레벨 |
5. 결론
인증과 인가는 웹 애플리케이션 보안의 두 축입니다.
- 인증이 “너 누구야?”,
- 인가가 **“너 이거 해도 돼?”**를 묻는다면,
이 둘의 구분은 보안의 근간을 지키는 일입니다. - 전통적인 웹 로그인이라면 세션 기반이 여전히 유효
- 모바일, SPA, API 서버 등 확장성이 필요한 환경이라면 JWT
- 소셜 로그인, 인증 연동 서비스를 구축해야 한다면 OAuth2
스프링부트 환경에서는 Spring Security를 통해 이 두 가지를 효과적으로 구현할 수 있으며,
JWT나 OAuth2를 활용하면 유연하면서도 확장성 있는 인증/인가 시스템을 구성할 수 있습니다.
기술을 도구로만 바라보지 말고, 서비스 아키텍처와 요구사항에 따라 선택하는 것이 핵심입니다.
728x90
'Security보안' 카테고리의 다른 글
침투 테스트(Penetration Testing) 유형 비교: 블랙 박스, 화이트 박스, 그레이 박스 (0) | 2025.03.29 |
---|---|
랜섬웨어 감염 시 대응법: 몸값 지불? 복구? 최선의 선택은? (1) | 2025.03.19 |
직렬화(Serialization)와 역직렬화(Deserialization): 데이터전송, 저장시 필요성과 보안 취약점 및 해결 방법 (0) | 2025.03.13 |
피싱, 스미싱, 파밍의 유래와 차이점, 그리고 위험성 🚨 (2) | 2025.03.12 |
내 개인정보는 해킹으로부터 지금 안전한가? 🔐 (0) | 2025.03.12 |