남잭슨의 개발 블로그

구글 로그인(GIS) 설정: 승인된 출처와 리다이렉트 URI 확인 본문
개발일지

구글 로그인(GIS) 설정: 승인된 출처와 리다이렉트 URI 확인

남잭슨 2026. 11. 1. 09:00

Google Identity Services(GIS) 웹 로그인에서는 승인된 출처에 버튼 페이지의 프로토콜·호스트·포트를 등록합니다. 리다이렉트로 결과를 받는 경우에는 서버 경로까지 포함한 URI도 등록해야 합니다. 두 설정은 같은 웹 클라이언트 ID를 기준으로 비교하세요. GIS 설정 문서

대상은 GIS 웹 로그인 버튼입니다. 로그인은 ID 토큰으로 사용자 신원을 확인하는 과정이며, Drive·Calendar 등 Google API 접근 권한 요청은 별도 흐름입니다. 아래 결과 수신 표는 JavaScript API 기준이고, HTML API의 차이도 따로 설명합니다. 로그인 인증과 API 권한의 구분

1. 웹 클라이언트 ID부터 확인하기

Google Cloud Console의 Google Auth Platform에서 대상 프로젝트를 선택합니다. 처음 설정하는 프로젝트라면 시작 안내에 따라 앱 등록과 Branding 등 필수 항목을 먼저 완료합니다. Clients에서 새 클라이언트를 만든다면 애플리케이션 유형을 Web application으로 고릅니다. 이미 사용하는 웹 클라이언트가 있다면 코드가 그 클라이언트의 ID를 사용하는지 먼저 확인합니다. Branding의 앱 이름·지원 연락처·사이트 정보도 실제 서비스에 맞게 설정합니다. 클라이언트 생성과 Branding 설정 · 앱 등록 선행 조건

값의미브라우저 코드에서의 취급
클라이언트 IDGoogle에 어떤 앱의 요청인지 알리는 식별 값GIS의 client_id에 사용. 이 글에서는 REPLACE_WITH_WEB_CLIENT_ID로 표시
클라이언트 시크릿기밀 값을 보관할 수 있는 서버의 OAuth 처리에 쓰는 값브라우저에 넣지 않음. GIS 로그인 버튼의 초기화 값도 아님

GIS 로그인 버튼에는 client_id를 사용합니다. 클라이언트 시크릿은 브라우저 코드나 브라우저에 포함되는 환경변수에 넣지 마세요. 클라이언트 ID와 시크릿 · GIS client_id

2. 승인된 JavaScript 출처에 경로를 넣지 않기

승인된 자바스크립트 원본(Authorized JavaScript origins)은 로그인 버튼이 실행되는 출처입니다. 출처에는 프로토콜·호스트·사용하는 포트가 들어가고, 페이지 경로·쿼리·프래그먼트는 들어가지 않습니다. 아래는 설명용 주소로 비교한 예시입니다. 승인된 출처와 URI의 등록 규칙

버튼이 있는 페이지: https://app.example.com/login
승인된 출처:       https://app.example.com

로컬 페이지:       http://localhost:5173/login
포트가 있는 출처:  http://localhost:5173

로컬 개발에서는 Google 설정 문서의 안내에 따라 http://localhost와 실제 포트가 포함된 출처를 함께 등록합니다. http://localhost:5173과 http://localhost:3000, localhost와 127.0.0.1을 같은 주소로 취급하지 마세요. 운영 환경에서는 HTTPS 주소를 사용합니다. 로컬 개발 출처 설정

승인된 출처를 등록했다면 로그인 결과를 받을 방식을 정합니다. 다음 표는 GIS JavaScript API로 로그인 버튼을 구성하는 경우입니다. 기본 ux_mode는 popup이며, 리다이렉트 방식은 redirect로 지정합니다. 여기서 받는 로그인 결과는 ID 토큰이며, 필드 이름은 credential입니다. 버튼의 결과 수신 방식

설정 방식결과를 받는 곳준비할 처리
ux_mode: "popup"
callback: handleCredentialResponse
직접 정의한 콜백 함수의 response.credential받은 ID 토큰을 서비스 서버로 안전하게 전달하고 서버에서 검증
ux_mode: "redirect"
login_uri: "https://app.example.com/auth/google"
login_uri로 들어오는 POST 본문의 credentialPOST 수신·본문 파싱·요청 보호·ID 토큰 검증을 수행하는 서버 경로

표의 handleCredentialResponse는 직접 구현할 함수의 예시 이름입니다. 버튼 렌더링과 서버 처리를 포함한 완성 코드가 아닙니다. JavaScript API의 팝업 모드에서는 callback이 필요하며 login_uri를 넣어도 자동 서버 제출 방식으로 바뀌지 않습니다. callback과 login_uri의 역할

리다이렉트를 선택했다면 결과를 받을 login_uri를 승인된 리다이렉트 URI에도 등록합니다. JavaScript API의 팝업 콜백 방식을 선택했다면 아래 리다이렉트 서버 경로를 만드는 단계는 해당하지 않습니다.

콘솔 항목설명용 값확인할 점
Authorized JavaScript originshttps://app.example.com실제 버튼 페이지의 출처와 일치하는가? /login 같은 경로를 넣지 않았는가?
Authorized redirect URIshttps://app.example.com/auth/google리다이렉트 방식의 login_uri와 정확히 일치하고 POST를 받을 수 있는 주소인가?

리다이렉트 수신 주소는 프로토콜·호스트·포트·경로까지 비교합니다. /auth/google과 /auth/google/처럼 끝의 슬래시가 다른 경우도 확인하세요. 코드는 다른 클라이언트 ID를 사용하면서 콘솔에서는 엉뚱한 클라이언트의 주소만 고치고 있지 않은지도 함께 봅니다. GIS의 login_uri는 해당 클라이언트에 등록된 리다이렉트 URI와 정확히 일치해야 합니다. login_uri 일치 조건

리다이렉트 주소를 단순한 화면 경로로만 만들면 안 됩니다. 이 GIS 방식은 URL의 ?code=를 읽는 예제와 다르게, ID 토큰을 POST 본문으로 받습니다. 프런트엔드 라우트만 있거나 서버가 GET만 처리하면 돌아온 뒤 404·405가 나거나 본문 값을 읽지 못할 수 있습니다. 서버 측 OAuth/OIDC 인가 코드 흐름을 사용하는 인증 라이브러리에는 이 GIS의 POST 수신 규칙을 그대로 적용하지 마세요. 리다이렉트 엔드포인트의 POST 처리

Google 로그인도 서버 측 OIDC 코드 흐름으로 구현할 수 있습니다. 이 경우에는 콜백의 code를 서버에서 토큰으로 교환하므로, 사용 중인 인증 도구의 응답 계약을 따라야 합니다. Google OpenID Connect의 서버 흐름

HTML의 data-* 속성으로 버튼을 만드는 방식은 규칙이 조금 다릅니다. HTML API는 팝업 모드에서도 data-login_uri로 서버 제출을 선택할 수 있고, data-callback도 지정했다면 콜백이 우선합니다. 따라서 “팝업이면 항상 콜백”이라는 설명을 모든 GIS 방식에 적용하지 말고, 사용하는 코드가 HTML API인지 JavaScript API인지부터 확인하세요. HTML API의 결과 처리 우선순위

GIS JavaScript 로그인 버튼의 팝업 콜백과 리다이렉트 POST가 서버 검증·회원 연결로 이어지는 설명용 흐름도

구글 로그인 결과를 받는 두 경로. 설명용 도식입니다. GIS JavaScript API의 팝업은 콜백, 리다이렉트는 POST 본문에서 ID 토큰을 받은 뒤 서버에서 검증합니다.

4. 오류 메시지에 따라 확인할 곳 좁히기

주소 관련 오류가 보인다고 승인된 출처와 리다이렉트 URI를 모두 바꾸기보다, 어느 단계가 실패했는지 먼저 구분합니다. 아래 점검표에서 실제 오류 메시지에 해당하는 항목부터 확인하세요.

오류·증상먼저 확인할 것확인 근거
origin_mismatch현재 페이지의 프로토콜·호스트·포트를 사용하는 클라이언트의 승인된 출처와 비교. 개발·운영 클라이언트 ID 혼용도 확인출처 등록 규칙
redirect_uri_mismatch실제 login_uri와 같은 클라이언트에 등록한 리다이렉트 URI를 전체 문자열로 비교리다이렉트 일치 조건
돌아온 주소에서 404·405, 또는 credential이 비어 있음서버 경로가 POST를 받는지, 실제 요청의 Content-Type에 맞게 본문을 파싱하는지 확인. GET 쿼리에서만 찾고 있지 않은지 점검POST 수신 계약
팝업 이후 결과 처리 함수가 실행되지 않음JavaScript API의 callback 등록, HTML·JavaScript 방식의 중복 구성을 확인. 브라우저 오류가 있으면 라이브러리 로드·CSP·COOP 조건과 대조버튼 구성 · 브라우저 설정
서버에서 aud 검증 실패토큰을 발급받은 클라이언트 ID와 서버가 허용한 클라이언트 ID가 맞는지 확인. 검증을 끄는 방식으로 해결하지 않음ID 토큰 검증
특정 계정에서만 접근이 거부됨앱의 대상 사용자·게시 상태·요청 권한과 Workspace 관리자 정책을 확인. 출처 오류와 구분앱 상태와 조직 정책
Google 인증 뒤에도 서비스에서는 로그아웃 상태ID 토큰 전달·검증 이후 회원 연결과 서비스 세션 생성·유지가 구현됐는지 확인서비스 세션의 처리 범위

출처·리다이렉트 URI를 고친 직후라면 반영 시간도 고려하세요. Google은 변경 적용에 5분에서 몇 시간이 걸릴 수 있다고 안내합니다. 사용하는 클라이언트 ID와 등록값이 맞는지 확인한 뒤 재시험하고, 같은 값을 반복해서 바꾸지 않도록 합니다. 주소 설정 변경의 반영 시간

테스트 사용자 목록만 추가하면 모든 접근 거부가 해결되는 것은 아닙니다. Google은 Sign in with Google 인증만 사용하거나 기본 이름·이메일·프로필 범위만 요청하는 경우에 테스트 사용자 목록·테스트 경고·7일 후 권한 만료의 예외를 안내합니다. 다른 OAuth 범위도 요청하면 이 예외를 적용할 수 없습니다. 조직 내부용 앱이나 Workspace 정책의 제한도 별도로 확인해야 합니다. Manage App Audience의 Testing 예외

5. 서버 검증·회원 연결·세션 확인하기

  1. 설정값 확인: 같은 웹 클라이언트 ID를 기준으로 승인된 출처와 선택한 수신 방식을 비교합니다. 주소는 설명용 값을 실제 환경에 맞게 바꿉니다.
  2. 결과 수신 확인: JavaScript API 기준으로 팝업이면 콜백의 credential, 리다이렉트이면 POST 본문의 credential 도착 여부를 확인합니다. 토큰 원문을 공개 로그나 스크린샷에 남기지 않습니다.
  3. 요청과 ID 토큰 검증: GIS가 직접 제출하는 POST에서는 쿠키와 본문의 g_csrf_token을 대조하고, 누락되거나 다르면 거부합니다. 콜백에서 자체 요청을 만들어 서버로 보낸다면 그 경로에 맞는 CSRF 보호도 구현해야 합니다.
  4. 회원과 연결: 검증된 Google 사용자 식별자 sub를 기준으로 서비스 회원과 연결합니다. 브라우저에서 토큰을 풀어 이메일이 보인다는 것만으로 인증을 완료하지 않습니다.
  5. 서비스 결과 확인: 신규 가입과 재로그인, 취소·실패 시 처리, 로그인 후 세션 유지까지 확인합니다. Google 로그인 창이 닫힌 것과 서비스에 로그인된 것은 구분합니다.

서버에서는 공식 인증 라이브러리 등을 사용해 ID 토큰의 서명, 수신 대상 aud, 발급자 iss, 만료 exp를 검증합니다. 이메일 주소를 영구적인 사용자 식별자로 사용하는 대신 검증된 sub를 사용합니다. 구체적인 서버 코드는 선택한 언어·프레임워크에 맞춰 구현해야 합니다. 서버 검증과 사용자 식별 기준

Google 공식 문서를 바탕으로 정리한 설정 점검 가이드입니다. 주소·식별값·도식은 설명용이며, 실제 로그인·토큰 검증·회원가입을 실행한 결과는 포함하지 않았습니다.

공식 문서 재확인·원고 수정일: 2026년 10월 26일.

Comments