OAuth 소셜 로그인 🌐

Lzhtk·2026년 1월 18일

오늘은 OAuth를 통한 소셜 로그인 방식 중에서 Redirect 방식에 대해 알아보자 ❗

요즘 대부분의 웹 서비스에서는
구글, 카카오, 네이버와 같은 OAuth 기반 소셜 로그인이 기본처럼 제공된다.
OAuth 2.0의 개념이나 Authorization Code Grant 흐름 자체는 이미 정리되어 있다.
하지만 실제 프로젝트에 이를 적용해보며 이런 궁금증이 생겼다.

  • 로그인 버튼을 누르면 어떤 요청이 어디로 이동할까? 🤷‍♀️
  • 인가 코드는 누가 받고, 토큰은 누가 요청할까?🤷‍♂️
  • 소셜 계정과 우리 서비스 계정은 어떻게 연결해야 할까?🤷‍♀️
  • JWT는 어느 시점에서 발급하는 게 맞지?🤷‍♂️

이러한 궁금증이 생겼기에 이번 글에서는 OAuth 개념 설명보다는,
Spring 기반 백엔드 프로젝트에서 Redirect 방식 소셜 로그인을 어떻게 설계하고 구현했는지 실제 흐름을 중심으로 정리해보려고 한다.

참고 - OAuth 2.0 와 Authorization Code Grant 🔑
https://velog.io/@kinggusrl3/OAuth-2.0-%EC%99%80-Authorization-Code-Grant


👀 전체 로그인 흐름 한 눈에 보기

내가 구현한 Redirect 기반 OAuth 로그인 흐름은 다음과 같다.

[1] 프론트 로그인 버튼 클릭
        ↓
[2] GET /auth/social/redirect?provider=google|kakao
        ↓
[3] 백엔드가 provider별 OAuth 인가 URL 생성
        ↓
[4] Authorization Server로 Redirect
        ↓
[5] 사용자 로그인 및 동의
        ↓
[6] GET /auth/social/callback/{provider}?code=&state=[7] 인가 코드로 Access Token 교환
        ↓
[8] userinfo API 호출
        ↓
[9] 소셜 계정 연결 / 신규 회원 생성
        ↓
[10] JWT 발급 (Access + Refresh)[11] Refresh Token → httpOnly 쿠키 저장
        ↓
[12] 프론트 콜백 URL로 Redirect

이 구조의 핵심은 OAuth는 외부 인증을 위임하고,
서비스는 내부 인증 ( JWT )은 우리가 직접 책임
진다는 것이다.


0️⃣ 앱 등록

OAuth 기반 소셜 로그인을 사용하기 위해서는
각 소셜 플랫폼에 OAuth 애플리케이션 등록이 선행되어야 한다.

이 과정은 단순한 설정이 아니라 우리 서비스가 해당 플랫폼의 OAuth Client임을 등록하는 절차이다.

✅ Google OAuth

  • Google Cloud Console에서 프로젝트 생성
  • OAuth Client ID 생성
  • 승인된 Redirect URI 등록

예시

http://localhost:8080/auth/social/callback/google

이를 통해 발급받는 값은 다음 두 가지이다.

  • Client ID
  • Client Secret

✅ Kakao OAuth

  • Kakao Developers에서 애플리케이션 생성
  • REST API 키 발급
  • Redirect URI 등록

예시

http://localhost:8080/auth/social/callback/kakao

⚠️ 공통 주의사항

  • redirect URI는 정확히 일치하여야 한다
  • Client Secret은 절대 프론트엔드에 노출 금지

해당 값들은 이후 인가 코드 → 토큰 교환 단계에서
서버가 Authorization Server와 통신할 때 사용됨


1️⃣ 프론트 → OAuth 로그인 시작

프론트엔드에서는 소셜 로그인 버튼 클릭시 다음 요청만 백엔드로 전달한다.

GET /auth/social/redirect?provider=google

이 방식의 장점은 명확하다.

  • 프론트에서 OAuth 세부 로직을 몰라도 됨
  • client_id, redirect_uri 노출 방지
  • provider 변경 및 확장 용이

이 구조에서 OAuth 흐름의 시작점은 항상 백엔드가 된다.

내가 백엔드 개발자이기에 프론트를 최소한으로 건드는 해당 구조를 선택하게 되었다.


2️⃣ provider별 인가 URL 생성

백엔드는 전달받은 provider 값에 따라 각 OAuth 제공자에 맞는 인가 URL을 직접 생성한다.

이때 포함되는 값은 다음과 같다.

  • client_id
  • redirect_uri
  • scope
  • response_type=code
  • state ( CSRF 방지용 )

state 값은 서버에서 생성하여 저장하고, 콜백 시 동일한 값인지 검증한다.


3️⃣ Authorization Server로 Redirect

인가 URL이 완성되면 백엔드는

302 Redirect

응답을 통해 사용자의 브라우저를 Google 또는 Kakao 로그인 페이지로 이동시킨다.

이 시점부터 로그인, 비밀번호 입력, 동의 화면은 모두 provider의 책임 영역이다.


4️⃣ 로그인 완료 후 Callback 수신

사용자가 인증과 동의를 완료하면 provider는 사전에 등록된 redirect URI로 다시 이동시킨다.

GET /auth/social/callback/{provider}
    ?code=xxxx
    &state=yyyy

이 시점에서 전달되는 것은 Access Token이 아니라 인가 코드이다.

  • 1회용
  • 짧은 만료 시간
  • 토큰 교환을 위한 중간 수단

5️⃣ 인가 코드로 Access Token 교환

백엔드는 인가 코드를 이용해 provider의 토큰 발급 API에서 서버 간 통신을 수행한다.

이때 요청에는 다음 정보가 포함된다.

  • client_id
  • client_secret
  • code
  • redirect_uri
  • grant_type=authorization_code

이 과정은 브라우저를 거치지 않는 서버 간 통신으로 이루어지며, Access Token은 외부에 노출되지 않는다.


6️⃣ userinfo API 조회

발급받은 Access Token으로 각 provider의 사용자 정보 API를 호출한다.

이를 통해 다음과 같은 정보를 획득한다.

  • provider user id
  • 이메일
  • 닉네임
  • 프로필 이미지

7️⃣ 소셜 계정 연결 구조

OAuth 로그인은 단순 로그인 기능이 아니라
계정 연결(account linking) 문제를 함께 고려해야 한다.

나는 다음과 같은 구조로 설계했다.

User
 └── SocialAccount (provider, providerUserId)

처리 흐름은 다음과 같다.
1️⃣ provider + providerUserId 기준으로 조회
2️⃣ 기존 연동 계정 존재 → 해당 User 로그인
3️⃣ 연동 계정 없음 → 신규 User 생성
4️⃣ SocialAccount 저장 및 연결

이 구조를 통해:

  • 하나의 계정에 여러 소셜 연동 가능
  • 추후 일반 로그인 확장 가능
  • 계정 통합 정책 유연성 확보

가 가능해졌다.


8️⃣ JWT 발급 시점

OAuth 인증은 외부 인증일 뿐, 우리 서비스의 인증 체계는 JWT 기반이다.
따라서 소셜 로그인 성공 시:

  • Access Token (짧은 만료)
  • Refresh Token (긴 만료)

을 직접 발급한다.


9️⃣ Refresh Token은 httpOnly 쿠키로 저장

보안을 위해 Refresh Token은 다음 정책을 사용했다.

  • httpOnly 쿠키
  • JS 접근 불가
  • Secure 옵션 적용

이를 통해 XSS 공격 시 토큰 탈취 위험을 줄이고, 재발급 API를 통한 갱신만 가능하도록 설계했다.


🔁 프론트로 최종 Redirect

모든 인증 처리가 완료되면 백엔드는 프론트엔드 콜백 주소로 다시 redirect 한다.

성공 시:

/auth/callback?token=ACCESS_TOKEN
/auth/callback?error=LOGIN_FAILED

프론트는 이 토큰을 기준으로 로그인 상태를 유지한다.


✅ 이 구조에서 중요하게 가져간 원칙

  • OAuth는 로그인 수단이다
  • 인증 책임은 서비스가 직접 가진다
  • 민감한 정보는 서버에서만 처리한다
  • 프론트는 인증 흐름을 트리거하는 역할만 한다

즉, 외부 인증은 위임하되
서비스 보안과 세션 관리는 직접 설계한다.


마무리 🔚

이번 글에서는 OAuth Redirect 방식을 Spring 기반 프로젝트에서 실제로 어떻게 설계하고 구현했는지 흐름 중심으로 정리하였다.
단순히 소셜 로그인 구현이 아니라,

  • OAuth 앱 등록
  • Redirect 흐름 제어
  • 인가 코드 교환
  • 계정 연결 구조
  • JWT 및 Refresh Token 전략
    까지 함께 고민한 경험이었다.
    OAuth는 라이브러리로 쉽게 붙일 수 있지만, 그 내부 흐름을 이해하고 설계 기준을 명확히 하는 것은 이후 인증 구조를 확장하는 데 큰 도움이 될 것이다 💯

0개의 댓글