연결된 계정 로그인

Google 계정 연결을 이용하면 Google 계정 소유자가 빠르고 원활하며 안전하게 내 서비스에 연결하고 Google과 데이터를 공유할 수 있습니다.

연결된 계정 로그인을 사용하면 이미 Google 계정이 서비스에 연결된 사용자에 대해 Google 계정으로 원탭 로그인을 사용 설정할 수 있습니다. 이렇게 하면 사용자 이름과 비밀번호를 다시 입력하지 않고도 클릭 한 번으로 로그인할 수 있어 사용자 환경이 개선됩니다. 또한 사용자가 서비스에서 중복 계정을 만들 가능성을 줄입니다.

요구사항

연결된 계정 로그인을 구현하려면 다음 요구사항을 충족해야 합니다.

  • OAuth 2.0 승인 코드 흐름을 지원하는 Google 계정 OAuth 연결이 구현되어 있습니다. OAuth 구현에는 다음 엔드포인트가 포함되어야 합니다.
    • 승인 엔드포인트를 사용하여 승인 요청을 처리합니다.
    • 토큰 엔드포인트를 사용하여 액세스 및 갱신 토큰에 대한 요청을 처리합니다.
    • userinfo 엔드포인트를 사용하여 연결된 계정에 대한 로그인 프로세스 중에 사용자에게 표시되는 연결된 사용자에 대한 기본 계정 정보를 검색합니다.
  • Android 앱이 있습니다.

사용 방법

전제 조건 : 사용자가 이전에 Google 계정을 서비스 계정과 연결했습니다.

  1. 원탭 로그인 과정에서 연결된 계정을 표시하도록 선택합니다.
  2. 연결된 계정으로 서비스에 로그인할 수 있는 옵션이 포함된 원탭 로그인 메시지가 사용자에게 표시됩니다.
  3. 사용자가 연결된 계정으로 계속 진행하기로 선택하면 Google은 승인 코드를 저장하도록 토큰 엔드포인트로 요청을 전송합니다. 요청에는 서비스에서 발급한 사용자의 액세스 토큰과 Google 승인 코드가 포함됩니다.
  4. Google 승인 코드를 사용자의 Google 계정 관련 정보가 포함된 Google ID 토큰으로 교환합니다.
  5. 또한 인증 과정이 완료되면 앱에서 ID 토큰을 수신하며, 사용자가 앱에 로그인할 때 이 토큰을 서버에서 수신한 ID 토큰의 사용자 식별자와 대조합니다.
연결된 계정 로그인을 클릭합니다.
그림 1. 연결된 계정 로그인 흐름 사용자의 기기에 로그인된 계정이 여러 개 있는 경우 계정 선택기가 표시될 수 있으며 연결된 계정을 선택한 경우에만 연결된 계정 로그인 보기로 이동합니다.

Android 앱에서 연결된 계정 로그인 구현

Android 앱에서 연결된 계정 로그인을 지원하려면 Android 구현 가이드의 안내를 따르세요.

Google의 승인 코드 요청 처리

Google은 토큰 엔드포인트에 POST 요청을 하여 승인 코드를 저장합니다. 이 코드는 사용자의 ID 토큰으로 교환됩니다. 요청에는 사용자의 액세스 토큰 및 Google에서 발급한 OAuth2 승인 코드가 포함됩니다.

승인 코드를 저장하기 전에 client_id으로 식별되는 액세스 토큰을 Google에 부여했는지 확인해야 합니다.

HTTP 요청

샘플 요청

POST /token HTTP/1.1
Host: server.example.com
Content-Type: application/x-www-form-urlencoded

code=GOOGLE_AUTHORIZATION_CODE
&grant_type=urn:ietf:params:oauth:grant-type:reciprocal
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&access_token=ACCESS_TOKEN

토큰 교환 엔드포인트는 다음 요청 매개변수를 처리할 수 있어야 합니다.

토큰 엔드포인트 매개변수
code 필수 Google OAuth2 승인 코드
client_id 필수 Google에 발급한 클라이언트 ID
client_secret Google에 발급한 필수 클라이언트 비밀번호
access_token 필수 Google에 발급한 액세스 토큰입니다. 이를 사용하여 사용자의 컨텍스트를 가져옵니다.
grant_type 필수 값은 urn:ietf:params:oauth:grant-type:reciprocal로 설정해야 합니다.

토큰 교환 엔드포인트는 다음을 실행하여 POST 요청에 응답해야 합니다.

  • access_tokenclient_id에서 식별한 Google에 부여되었는지 확인합니다.
  • 요청이 유효하고 인증 코드가 Google ID 토큰으로 성공적으로 교환된 경우 HTTP 200 (OK) 응답을, 요청이 유효하지 않은 경우 HTTP 오류 코드로 응답합니다.

HTTP 응답

성공

HTTP 상태 코드 200 OK 반환

성공 응답 샘플
HTTP/1.1 200 OK
Content-Type: application/json
Cache-Control: no-store
Pragma: no-cache
{}

오류

잘못된 HTTP 요청이 있는 경우 다음 HTTP 오류 코드 중 하나로 응답합니다.

HTTP 상태 코드 본문 설명
400 {"error": "invalid_request"} 요청에 매개변수가 누락되어 서버에서 요청을 진행할 수 없습니다. 요청에 지원되지 않는 매개변수가 포함되어 있거나 매개변수가 반복되는 경우에도 반환될 수 있습니다.
401 {"error": "invalid_request"} 클라이언트 인증 실패(예: 요청에 잘못된 클라이언트 ID 또는 보안 비밀이 포함된 경우)
401 {"error": "invalid_token"}

응답 헤더에 'WWW-Authentication: Bearer' 인증 챌린지 포함

파트너 액세스 토큰이 잘못되었습니다.
403 {"error": "insufficient_permission"}

응답 헤더에 'WWW-Authentication: Bearer' 인증 챌린지 포함

파트너 액세스 토큰에 상호 OAuth를 수행하는 데 필요한 범위가 없습니다.
500 {"error": "internal_error"} 서버 오류

오류 응답에는 다음 필드가 포함되어야 합니다.

오류 응답 필드
error 필수 오류 문자열
error_description 사람이 읽을 수 있는 오류 설명
error_uri 오류에 관한 세부정보를 제공하는 URI
샘플 오류 400 응답
HTTP/1.1 400 Bad Request
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache

{
  "error": "invalid_request",
  "error_description": "Request was missing the 'access_token' parameter."
}

ID 토큰용 승인 코드 교환

받은 승인 코드를 사용자의 Google 계정 관련 정보가 포함된 Google ID 토큰으로 교환해야 합니다.

승인 코드를 Google ID 토큰으로 교환하려면 https://oauth2.googleapis.com/token 엔드포인트를 호출하고 다음 매개변수를 설정합니다.

요청 필드
client_id 필수: API 콘솔 사용자 인증 정보 페이지에서 가져온 클라이언트 ID입니다. 일반적으로 이름이 New Actions on Google App인 사용자 인증 정보입니다.
client_secret 필수: API 콘솔 사용자 인증 정보 페이지에서 가져온 클라이언트 보안 비밀번호
code 필수: 초기 요청에서 전송된 승인 코드
grant_type 필수 OAuth 2.0 사양에 정의된 대로 이 입력란의 값은 authorization_code로 설정해야 합니다.
샘플 요청
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=GOOGLE_AUTHORIZATION_CODE
&grant_type=authorization_code
&client_id=GOOGLE_CLIENT_ID
&client_secret=GOOGLE_CLIENT_SECRET

Google은 수명이 짧은 액세스 토큰과 갱신 토큰이 포함된 JSON 객체를 반환함으로써 이 요청에 응답합니다.

응답에는 다음 필드가 포함됩니다.

응답 필드
access_token 애플리케이션에서 Google API 요청을 승인하기 위해 전송하는 Google이 발급한 액세스 토큰
id_token ID 토큰에는 사용자의 Google 계정 정보가 포함됩니다. 응답 유효성 검사 섹션에는 ID 토큰 응답을 디코딩하고 유효성을 검사하는 방법에 대한 세부정보가 포함되어 있습니다.
expires_in 액세스 토큰의 남은 수명(초)
refresh_token 새 액세스 토큰을 얻는 데 사용할 수 있는 토큰입니다. 갱신 토큰은 사용자가 액세스 권한을 취소할 때까지 유효합니다.
scope 이 필드의 값은 연결된 계정 로그인 사용 사례의 경우 항상 openid로 설정됩니다.
token_type 반환된 토큰의 유형입니다. 현재 이 필드의 값은 항상 Bearer(으)로 설정됩니다.
샘플 응답
HTTP/1.1 200 OK
Content-type: application/json; charset=utf-8

{
  "access_token": "Google-access-token",
  "id_token": "Google-ID-token",
  "expires_in": 3599,
  "token_type": "Bearer",
  "scope": "openid",
  "refresh_token": "Google-refresh-token"
}


POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=Google authorization code
&grant_type=authorization_code
&client_id=Google client id
&client_secret=Google client secret

ID 토큰 응답 유효성 검사

Validate and decode the JWT assertion

You can validate and decode the JWT assertion by using a JWT-decoding library for your language. Use Google's public keys, available in JWK or PEM formats, to verify the token's signature.

When decoded, the JWT assertion looks like the following example:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

In addition to verifying the token's signature, verify that the assertion's issuer (iss field) is https://accounts.google.com, that the audience (aud field) is your assigned client ID, and that the token has not expired (exp field).

Using the email, email_verified and hd fields you can determine if Google hosts and is authoritative for an email address. In cases where Google is authoritative the user is currently known to be the legitimate account owner and you may skip password or other challenges methods. Otherwise, these methods can be used to verify the account prior to linking.

Cases where Google is authoritative:

  • email has a @gmail.com suffix, this is a Gmail account.
  • email_verified is true and hd is set, this is a G Suite account.

Users may register for Google Accounts without using Gmail or G Suite. When email does not contain a @gmail.com suffix and hd is absent Google is not authoritative and password or other challenge methods are recommended to verify the user. email_verfied can also be true as Google initially verified the user when the Google account was created, however ownership of the third party email account may have since changed.