OAuth2와 인증/인가의 모든 것: 원리부터 실전까지
1. 인증(Authentication)과 인가(Authorization)란?
인증의 정의
인증은 사용자가 누구인지 신원을 확인하는 과정입니다. 예를 들어, 웹사이트 로그인 시 아이디와 비밀번호를 입력하면 서버는 해당 정보가 맞는지 확인합니다. 이 과정에서 서버는 사용자의 신원을 검증하고, 인증에 성공하면 세션이나 토큰을 발급합니다. 인증은 ‘너는 누구냐?’에 대한 답입니다.
인가의 정의
인가(Authorization)는 인증이 끝난 사용자가 어떤 자원에 접근할 수 있는지를 결정하는 과정입니다. 예를 들어, 관리자는 모든 데이터를 볼 수 있지만 일반 사용자는 자신의 정보만 볼 수 있습니다. 인가는 ‘너는 무엇을 할 수 있냐?’에 대한 답입니다.
2. OAuth2란 무엇인가?
OAuth2의 등장 배경과 필요성
과거에는 서비스 간 연동을 위해 아이디/비밀번호를 직접 입력하는 방식이 많았지만, 이는 보안상 매우 위험했습니다. OAuth2는 사용자의 비밀번호를 노출하지 않고, 제3자 서비스에 권한을 위임할 수 있게 해줍니다. 대표적으로 구글, 네이버, 카카오 소셜 로그인 등이 OAuth2 기반입니다.
OAuth2의 동작 원리
OAuth2는 여러 가지 플로우(Authorization Code, Implicit, Client Credentials, Resource Owner Password)를 지원합니다. 가장 많이 쓰이는 Authorization Code Flow의 예시는 다음과 같습니다.
- 사용자가 클라이언트(앱)에서 ‘구글로 로그인’ 버튼 클릭
- 클라이언트는 인증 서버(구글)에 인증 코드 요청
- 사용자는 구글 로그인 후 권한 동의
- 인증 서버는 클라이언트에 인증 코드 전달
- 클라이언트는 이 코드를 다시 인증 서버에 보내 Access Token을 발급받음
- Access Token으로 API 호출 및 자원 접근
- Access Token: 실제 자원 접근에 사용하는 토큰
- Refresh Token: Access Token이 만료됐을 때 갱신용
- Scope: 허용된 권한 범위(예: profile, email)
시퀀스 다이어그램
3. 실전: 코틀린으로 OAuth2 연동하기
Spring Security + OAuth2 Client 예시
@Configuration
@EnableWebSecurity
class SecurityConfig : WebSecurityConfigurerAdapter() {
override fun configure(http: HttpSecurity) {
http
.oauth2Login()
.and()
.authorizeRequests()
.antMatchers("/api/**").authenticated()
.anyRequest().permitAll()
}
}
- application.yml에 구글/카카오/네이버 Client ID, Secret 등 설정
- 컨트롤러에서 Principal 객체로 사용자 정보 활용
JWT 토큰 파싱 예시
val jwt = Jwts.parserBuilder()
.setSigningKey(secretKey)
.build()
.parseClaimsJws(token)
.body
println(jwt["email"])
4. OAuth2와 보안 고려사항
토큰 유출, 만료, 재발급, PKCE, HTTPS 적용 등
- Access Token은 반드시 HTTPS로만 전송
- Refresh Token은 서버에 안전하게 저장, 노출 주의
- PKCE(Proof Key for Code Exchange) 적용으로 보안 강화
- 토큰 만료 및 재발급 로직 구현 필수
5. 실전 활용 팁과 문제 해결
디버깅, 로그, 테스트, 실무에서 자주 겪는 문제와 해결법
- 토큰 파싱 오류: 시크릿 키, 알고리즘 불일치 확인
- 인증 서버와 시계 불일치: 서버 시간 동기화
- CORS 문제: Spring에서 CORS 설정 추가
6. 결론
OAuth2와 인증/인가의 원리를 이해하면, 다양한 서비스에서 안전하고 편리한 인증 시스템을 구축할 수 있습니다. 공식 문서와 실습을 병행해보세요.
- 참고자료: OAuth2 공식문서, Spring Security Docs