Social Login

유승현·2025년 8월 25일

SSABAB

목록 보기
3/3

소셜 로그인이란 OAuth2.0기반으로 사용자의 정보를 이용하여 다른 웹 사이트나 애플리케이션에 간편하게 로그인할 수 있도록 하는 기능

OAuth2.0이란?

참고 : https://datatracker.ietf.org/doc/html/rfc6749#section-1.1

사진으로 보는 프로토콜 요약

개요

OAuth는 인가 계층(authorization layer)을 도입하고 클라이언트의 역할과 리소스 소유자의 역할을 분리함으로써 이러한 문제들을 해결합니다.

  1. OAuth에서 클라이언트는 리소스 소유자에 의해 제어되고 리소스 서버에 의해 호스팅되는 리소스에 대한 접근을 요청하며, 리소스 소유자의 자격 증명과는 다른 별개의 자격 증명 집합을 발급받습니다.
  2. 리소스 소유자의 자격 증명을 사용하여 보호된 리소스에 접근하는 대신, 클라이언트는 액세스 토큰—특정 범위, 수명 및 기타 접근 속성을 나타내는 문자열—을 획득합니다.
  3. 액세스 토큰은 리소스 소유자의 승인을 받아 인가 서버에 의해 제3자 클라이언트에게 발급됩니다.
  4. 클라이언트는 이 액세스 토큰을 사용하여 리소스 서버가 호스팅하는 보호된 리소스에 접근합니다.

예를 들어, 최종 사용자(리소스 소유자)는 인쇄 서비스(클라이언트)에 자신의 사용자 이름과 비밀번호를 공유하지 않고도 사진 공유 서비스(리소스 서버)에 저장된 자신의 보호된 사진에 대한 접근 권한을 부여할 수 있습니다. 대신, 그녀는 사진 공유 서비스가 신뢰하는 서버(인가 서버)에 직접 인증하고, 이 서버는 인쇄 서비스에 위임 관련 특정 자격 증명(액세스 토큰)을 발급합니다.

이 명세는 HTTP([RFC2616])와 함께 사용하도록 설계되었습니다. HTTP 이외의 프로토콜을 통한 OAuth의 사용은 이 문서의 범위를 벗어납니다.

정보 문서로 발표된 OAuth 1.0 프로토콜([RFC5849])은 소규모의 임시 커뮤니티 노력의 결과물이었습니다. 이 표준 트랙 명세는 OAuth 1.0의 배포 경험뿐만 아니라, 더 넓은 IETF 커뮤니티로부터 수집된 추가적인 사용 사례 및 확장성 요구사항을 기반으로 합니다. OAuth 2.0 프로토콜은 OAuth 1.0과 하위 호환되지 않습니다. 두 버전은 네트워크 상에서 공존할 수 있으며, 구현체는 둘 다 지원하도록 선택할 수 있습니다. 그러나 이 명세의 의도는 새로운 구현이 이 문서에 명시된 대로 OAuth 2.0을 지원하고, OAuth 1.0은 기존 배포를 지원하기 위해서만 사용되도록 하는 것입니다. OAuth 2.0 프로토콜은 OAuth 1.0 프로토콜과 구현 세부 사항을 거의 공유하지 않습니다. OAuth 1.0에 익숙한 구현자는 이 문서의 구조와 세부 사항에 대한 어떠한 가정도 없이 접근해야 합니다.

나의 비유

사용자가 가게에서 어떤 물건을 구매하고자 한다. 사용자의 돈은 모두 은행에 있다.

이 상황에서 금액을 지불하기 위해 사용자가 자신의 “계좌번호”와 “비밀번호”를 달려주는 것은 최악이다.

가게 사장이 물건 값 이상의 비용을 출금할 수 있기 때문이다. 이를 방지하기 위해 사용자는 수표를 써주기로 한다.

  1. 수표에 “누가” 돈을 “얼마나” 출금할 수 있게 허가하는지 본인이 돈을 저축해둔 "은행”에서 수표를 작성해준다.
  2. 이를 가게 사장에게 제공하면 가게 사장은 해당 은행에 수표를 들고 가서 제출하고, 은행에서는 금고 접근 허가증을 발급해준다.
  3. 허가증을 가지고 가게 사장이 금고에 가면 금고 보안 요원이 허가증에 적힌 금액만큼 돈을 꺼내서 가게 사장에게 준다. 이를 받은 가게 사장은 사용자에게 물건을 제공한다.

Gemini로 이해하는 예제 및 설명

👨‍💻 초보 개발자도 이해하는 OAuth 2.0: 구글 소셜 로그인 파헤치기

안녕하세요! 이제 막 개발의 세계에 발을 들인 여러분을 위해, '인증'과 '인가'라는 복잡해 보이는 산을 함께 넘어보려 합니다. 그중에서도 현대 웹 서비스의 필수 기능인 OAuth 2.0에 대해 알아보겠습니다. RFC 6749 문서는 그 표준 명세지만, 처음 보면 외계어 같을 수 있죠. 제가 실제 '구글 소셜 로그인'이 어떻게 동작하는지 보여드리면서 쉽고 재미있게 풀어드리겠습니다.

🤔 OAuth 2.0, 대체 왜 필요한가요?

옛날 옛적, '찍스타그램'이라는 사진 편집 앱이 있다고 상상해봅시다. 이 앱은 여러분의 구글 포토에 있는 사진을 가져와서 편집하고 싶어 합니다. 어떻게 해야 할까요?

  • 나쁜 방법 👎: '찍스타그램' 앱에 여러분의 구글 아이디와 비밀번호를 직접 알려준다.
  • 문제점:
    1. 비밀번호 유출 위험: '찍스타그램'이 해킹당하면 내 구글 계정 정보가 통째로 넘어갑니다.
    2. 과도한 권한: '찍스타그램'은 사진만 필요한데, 내 이메일, 주소록, 구글 드라이브 파일까지 모두 접근할 수 있게 됩니다.
    3. 접근 차단 불가: '찍스타그램'의 접근만 막고 싶어도, 구글 비밀번호를 바꾸는 수밖에 없습니다. 그럼 다른 모든 서비스에서도 비밀번호를 바꿔야 하죠.

이런 끔찍한 문제를 해결하기 위해 등장한 것이 바로 OAuth (Open Authorization) 입니다. OAuth는 "비밀번호를 직접 주지 않고, 특정 권한만 제한적으로 부여하는 똑똑한 위임 방식"이라고 할 수 있습니다. 마치 호텔 룸키처럼, 레스토랑이나 수영장은 이용할 수 있지만 다른 손님의 방은 열 수 없는 '제한된 키'를 발급해주는 것과 같습니다.

등장인물 (Roles): OAuth 2.0의 4가지 역할

OAuth 2.0에는 4명의 주요 등장인물이 있습니다. 구글 로그인 예시와 함께 살펴보죠.

  1. Resource Owner (자원 소유자):
    • 설명: 보호된 자원(개인정보, 사진, 이메일 등)의 주인입니다.
    • 구글 로그인 예시: 바로 '나' 자신, 즉 서비스를 이용하려는 사용자입니다.
  2. Client (클라이언트):
    • 설명: 자원 소유자를 대신해 특정 자원에 접근하려고 요청하는 애플리케이션입니다.
    • 구글 로그인 예시: 우리가 로그인하려는 웹사이트나 앱 (예: awesome-service.com)
  3. Authorization Server (권한 서버):
    • 설명: 자원 소유자를 인증하고, 클라이언트에게 액세스 토큰(Access Token)을 발급해주는 서버입니다. "너는 이 권한을 가져도 좋아"라고 허락해주는 주체죠.
    • 구글 로그인 예시: Google의 인증/권한 서버 (accounts.google.com)
  4. Resource Server (자원 서버):
    • 설명: 보호된 자원을 실제로 가지고 있는 서버입니다. 액세스 토큰을 확인하고 요청에 응답합니다.
    • 구글 로그인 예시: Google의 API 서버 (예: 사용자의 프로필 정보를 제공하는 googleapis.com)

💡 Tip: 많은 경우, 권한 서버와 자원 서버는 같은 회사(Google)에 의해 운영되지만, 역할은 명확히 구분됩니다.


🔑 핵심 아이템: 토큰(Token)이란?

OAuth 2.0의 핵심은 '토큰'이라는 특별한 열쇠를 주고받는 것입니다.

  • Access Token (액세스 토큰):
    • 자원 서버에 접근할 수 있는 임시 출입증입니다.
    • 수명이 짧고(예: 1시간), "프로필 정보 읽기"와 같이 제한된 권한만 담고 있습니다.
    • 클라이언트(앱)는 이 토큰을 가지고 자원 서버(Google API)에 가서 "이 출입증 보여줄 테니, OOO님의 프로필 정보 좀 주세요!"라고 요청합니다.
  • Refresh Token (리프레시 토큰):
    • 액세스 토큰의 유효기간이 만료되었을 때, 새로운 액세스 토큰을 발급받기 위한 티켓입니다.
    • 수명이 길며(예: 6개월), 사용자가 다시 로그인하는 번거로움 없이 서비스를 계속 이용하게 해줍니다.
    • 액세스 토큰이 만료되면, 클라이언트는 이 리프레시 토큰을 권한 서버(Google)에 보내 "티켓 여기 있으니, 새 출입증(액세스 토큰)으로 바꿔주세요"라고 요청합니다.

🚀 구글 소셜 로그인 과정 (Authorization Code Grant 방식)

이제 모든 조각을 맞춰봅시다. OAuth 2.0의 가장 표준적이고 안전한 방식인 'Authorization Code Grant' 흐름을 통해 구글 소셜 로그인이 어떻게 이루어지는지 단계별로 살펴보겠습니다. (RFC 6749, Section 4.1)

1단계: 사용자의 로그인 요청

나 (Resource Owner)는 awesome-service.com(Client)에서 "Google로 로그인하기" 버튼을 클릭합니다.

이 간단한 클릭이 모든 여정의 시작입니다!

2단계: 권한 요청을 위한 Google로의 이동

awesome-service.com(Client)은 나를 Google 권한 서버로 보냅니다. 이때 그냥 보내는 게 아니라, 특별한 정보들을 담아서 보냅니다.

실제로는 브라우저가 아래와 같은 URL로 리디렉션됩니다.

https://accounts.google.com/o/oauth2/v2/auth? response_type=code& client_id=YOUR_CLIENT_ID.apps.googleusercontent.com& scope=openid%20profile%20email& redirect_uri=https://awesome-service.com/auth/google/callback& state=a_random_string_to_prevent_csrf

각 파라미터의 의미는 다음과 같습니다.

  • response_type=code: "나중에 인증 코드(Authorization Code)를 발급해주세요" 라는 의미입니다. 이게 바로 'Authorization Code Grant' 방식의 핵심입니다.
  • client_id: awesome-service.com이 구글에 미리 등록하고 발급받은 고유 식별자입니다. "제가 바로 그 앱이에요!"라고 신분을 밝히는 것이죠. (RFC, Section 2.2)
  • scope: 앱이 요청하는 권한의 범위입니다. 여기서는 'openid, profile, email' 정보에 접근하겠다고 요청하고 있습니다. (RFC, Section 3.3)
  • redirect_uri: 구글이 인증 절차를 마친 후, 사용자를 다시 돌려보낼 주소입니다. (awesome-service.com의 특정 경로) 보안을 위해 이 주소는 구글에 미리 등록되어 있어야 합니다. (RFC, Section 3.1.2)
  • state: CSRF(Cross-Site Request Forgery) 공격을 방지하기 위한 임의의 문자열입니다. 나중에 구글이 이 값을 그대로 돌려주면, awesome-service.com은 자기가 처음에 보낸 값이 맞는지 확인합니다. (RFC, Section 10.12)

3단계: 사용자의 동의

Google 권한 서버는 나에게 로그인 창을 보여줍니다. 로그인을 하면, "awesome-service.com이(가) 내 이름, 이메일 주소, 프로필 사진 등에 액세스하려고 합니다. 동의하시겠습니까?" 라는 동의 화면을 보여줍니다.

여기서 내가 "동의" 버튼을 누르면, 자원에 대한 접근을 허락하는 것입니다.

4단계: Google의 '인증 코드' 발급

내가 동의하면, Google 권한 서버는 2단계에서 지정된 redirect_uri로 나를 다시 돌려보냅니다. 이때 주소 뒤에 아주 짧은 시간만 유효한 임시 인증 코드(code)를 붙여줍니다.

브라우저는 다음 주소로 리디렉션됩니다.

https://awesome-service.com/auth/google/callback?code=A_TEMPORARY_AUTHORIZATION_CODE&state=a_random_string_to_prevent_csrf

중요: 아직 액세스 토큰이 아닙니다! 이건 그저 액세스 토큰으로 교환할 수 있는 '교환권'일 뿐입니다. 이 교환권은 브라우저(사용자)를 통해 전달되므로 비교적 덜 안전한 채널을 거칩니다.

5단계: '인증 코드'로 '액세스 토큰' 요청

awesome-service.com의 백엔드 서버는 브라우저를 통해 전달받은 인증 코드와 자신의 Client Secret(구글에 등록할 때 받은 비밀키)을 가지고, Google 권한 서버의 토큰 엔드포인트(Token Endpoint)에 직접 요청을 보냅니다.

이 과정은 사용자의 브라우저를 거치지 않고, 서버 대 서버로 안전하게 통신합니다. (RFC, Section 4.1.3)

Bash

awesome-service.com 서버가 Google 토큰 서버에 보내는 요청 예시 (curl)

curl --location --request POST 'https://oauth2.googleapis.com/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'code=A_TEMPORARY_AUTHORIZATION_CODE' \
--data-urlencode 'client_id=YOUR_CLIENT_ID.apps.googleusercontent.com' \
--data-urlencode 'client_secret=YOUR_CLIENT_SECRET' \
--data-urlencode 'redirect_uri=https://awesome-service.com/auth/google/callback' \
--data-urlencode 'grant_type=authorization_code'
  • grant_type=authorization_code: "제가 받아온 인증 코드를 드릴 테니, 액세스 토큰으로 바꿔주세요" 라는 의미입니다.

6단계: Google의 '액세스 토큰' 및 '리프레시 토큰' 발급

Google 권한 서버는 인증 코드, client_id, client_secret 등이 모두 유효한지 확인하고, 마침내 액세스 토큰리프레시 토큰을 awesome-service.com 서버에게 발급해줍니다.

성공 시 awesome-service.com 서버가 받는 응답(JSON)입니다. (RFC, Section 5.1)

{
  "access_token": "A_REAL_ACCESS_TOKEN_STRING",
  "expires_in": 3599,
  "refresh_token": "A_LONG_LIVED_REFRESH_TOKEN",
  "scope": "openid https://www.googleapis.com/auth/userinfo.profile https://www.googleapis.com/auth/userinfo.email",
  "token_type": "Bearer"
}

이제 awesome-service.com은 드디어 진짜 열쇠(액세스 토큰)를 손에 넣었습니다! 이 토큰들은 서버의 데이터베이스에 안전하게 저장됩니다.

7단계: '액세스 토큰'으로 사용자 정보 요청

awesome-service.com 서버는 발급받은 액세스 토큰을 이용해 Google 자원 서버(API 서버)에 내 프로필 정보를 요청합니다.

awesome-service.com 서버가 Google API 서버에 보내는 요청 예시

curl --location --request GET 'https://www.googleapis.com/oauth2/v2/userinfo' \
--header 'Authorization: Bearer A_REAL_ACCESS_TOKEN_STRING'`
  • Authorization: Bearer ...: HTTP 요청 헤더에 "이 Bearer(소지자) 토큰을 가지고 있으니 권한을 확인해주세요" 라는 의미로 액세스 토큰을 담아 보냅니다. (RFC, Section 7)

8단계: 자원 제공 및 로그인 완료

Google 자원 서버는 액세스 토큰이 유효한지 확인하고, awesome-service.com 서버에게 내 프로필 정보(이름, 이메일 등)를 보내줍니다.

이제 awesome-service.com은 내 정보를 받았으므로, 이 정보를 바탕으로 회원가입을 시키거나 로그인을 완료하고 서비스를 제공할 수 있게 됩니다.


✨ 요약 및 결론

복잡해 보이지만 핵심은 간단합니다.

  1. "비밀번호를 직접 주지 않는다."
  2. 사용자는 Google에 직접 로그인해서 권한을 '동의'만 한다.
  3. 앱은 '인증 코드(교환권)'를 임시로 받아온다.
  4. 앱의 '서버'가 안전하게 '액세스 토큰(진짜 열쇠)'으로 교환한다.
  5. 앱은 이 액세스 토큰으로 허락된 정보(예: 프로필)에만 접근한다.

이것이 바로 OAuth 2.0이 우리의 소중한 정보를 안전하게 지키면서도 편리한 소셜 로그인을 가능하게 하는 원리입니다. 이 흐름을 잘 이해하신다면, 앞으로 API 문서를 보거나 인증 관련 기능을 구현할 때 훨씬 더 자신감을 가질 수 있을 겁니다. 화이팅입니다! 🚀

profile
커피를 넣으면 코드가 나옵니다.

0개의 댓글