OAuth 및 Google 로그인을 사용한 간소화된 연결

개요

OAuth 기반 Google 로그인 간소화 연결OAuth 연결 외에 Google 로그인을 추가합니다. 이를 통해 Google 사용자에게 원활한 연결 환경이 제공되며 사용자가 Google 계정을 사용하여 서비스에 새 계정을 만들 수 있는 계정 생성도 가능합니다.

OAuth 및 Google 로그인을 사용하여 계정을 연결하려면 다음 일반 단계를 따르세요.

  1. 먼저 사용자에게 Google 프로필 액세스에 동의해 달라고 요청합니다.
  2. 프로필에 있는 정보를 사용하여 사용자 계정이 존재하는지 확인합니다.
  3. 기존 사용자의 경우 계정을 연결합니다.
  4. 인증 시스템에서 Google 사용자와 일치하는 결과를 찾을 수 없는 경우 Google에서 받은 ID 토큰을 검증하세요. 그러면 ID 토큰에 포함된 프로필 정보를 기반으로 사용자를 만들 수 있습니다.
이 그림은 사용자가 간소화된 연결 흐름을 사용하여 Google 계정을 연결하는 단계를 보여줍니다. 첫 번째 스크린샷은 사용자가 연결할 앱을 선택하는 방법을 보여줍니다. 두 번째 스크린샷을 통해 사용자는 서비스에 기존 계정이 있는지 확인할 수 있습니다. 세 번째 스크린샷을 통해 사용자는 연결할 Google 계정을 선택할 수 있습니다. 네 번째 스크린샷은 Google 계정을 앱과 연결하기 위한 확인입니다. 다섯 번째 스크린샷은 Google 앱에서 성공적으로 연결된 사용자 계정을 보여줍니다.

그림 1. 간소화된 연결을 통한 사용자 휴대전화의 계정 연결

간소화된 연결을 위한 요구사항

  • 기본 웹 OAuth 연결 흐름을 구현합니다. 서비스에서 OAuth 2.0을 준수하는 승인토큰 교환 엔드포인트를 지원해야 합니다.
  • 토큰 교환 엔드포인트는 JSON 웹 토큰 (JWT) 어설션을 지원하고 check, create, get 인텐트를 구현해야 합니다.

OAuth 서버 구현

토큰 교환 엔드포인트는 check, create, get 인텐트를 지원해야 합니다. 다음은 계정 연결 흐름을 통해 완료된 단계와 서로 다른 인텐트가 호출되는 시점을 보여줍니다.

  1. 사용자의 인증 시스템에 계정이 있나요? (사용자가 '예' 또는 '아니요'를 선택하여 결정)
    1. 예 : 사용자가 Google 계정과 연결된 이메일을 사용하여 플랫폼에 로그인하나요? (사용자가 '예' 또는 '아니요'를 선택하여 결정)
      1. 예 : 사용자의 인증 시스템에 일치하는 계정이 있나요? (check intent가 호출되어 확인)
        1. 예: get intent가 호출되고 가져오기 인텐트가 성공적으로 반환되면 계정이 연결됩니다.
        2. 아니요 : 새 계정을 만드시겠습니까? (사용자가 '예' 또는 '아니요'를 선택하여 결정)
          1. 예 : create intent가 호출되고 생성 인텐트가 성공적으로 반환되면 계정이 연결됩니다.
          2. 아니요 : 웹 OAuth 흐름이 트리거되고 사용자는 브라우저로 이동되며 사용자에게 다른 이메일과 연결할 수 있는 옵션이 제공됩니다.
      2. 아니요 : 웹 OAuth 흐름이 트리거되고 사용자가 사용 중인 브라우저로 이동되며 사용자에게 다른 이메일과 연결할 수 있는 옵션이 제공됩니다.
    2. 아니요 : 사용자의 인증 시스템에 일치하는 계정이 있나요? (check intent가 호출되어 확인)
      1. 예 : get intent가 호출되고 가져오기 인텐트가 성공적으로 반환되면 계정이 연결됩니다.
      2. 아니요: create intent가 호출되고 생성 인텐트가 성공적으로 반환되면 계정이 연결됩니다.

Check for an existing user account (check intent)

After the user gives consent to access their Google profile, Google sends a request that contains a signed assertion of the Google user's identity. The assertion contains information that includes the user's Google Account ID, name, and email address. The token exchange endpoint configured for your project handles that request.

If the corresponding Google account is already present in your authentication system, your token exchange endpoint responds with account_found=true. If the Google account doesn't match an existing user, your token exchange endpoint returns an HTTP 404 Not Found error with account_found=false.

The request has the following form:

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

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=check&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

Your token exchange endpoint must be able to handle the following parameters:

Token endpoint parameters
intent For these requests, the value of this parameter is check.
grant_type The type of token being exchanged. For these requests, this parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address.
client_id The client ID you assigned to Google.
client_secret The client secret you assigned to Google.

To respond to the check intent requests, your token exchange endpoint must perform the following steps:

  • Validate and decode the JWT assertion.
  • Check if the Google account is already present in your authentication system.
JWT 어설 션 유효성 검사 및 디코딩

해당 언어에 대한 JWT 디코딩 라이브러리를 사용하여 JWT 어설 션의 유효성을 검사하고 디코딩 할 수 있습니다 . JWK 또는 PEM 형식으로 제공되는 Google의 공개 키를 사용하여 토큰의 서명을 확인합니다.

디코딩 될 때 JWT 어설 션은 다음 예제와 같습니다.

{
  "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
}

토큰의 서명을 확인하는 것 외에도 어설 션의 발급자 ( iss 필드)가 https://accounts.google.com 이고 대상 ( aud 필드)이 할당 된 클라이언트 ID이며 토큰이 만료되지 않았는지 ( exp 들).

email , email_verifiedhd 필드를 사용하여 Google이 이메일 주소를 호스팅하고 권한이 있는지 확인할 수 있습니다. Google이 권한이있는 경우 사용자는 현재 합법적 인 계정 소유자로 알려져 있으며 비밀번호 또는 기타 질문 방법을 건너 뛸 수 있습니다. 그렇지 않으면 이러한 방법을 사용하여 연결하기 전에 계정을 확인할 수 있습니다.

Google이 권위있는 사례 :

  • email 에는 @gmail.com 접미사가 있으며 이는 Gmail 계정입니다.
  • email_verified 가 true이고 hd 가 설정되어있는 G Suite 계정입니다.

사용자는 Gmail 또는 G Suite를 사용하지 않고 Google 계정에 등록 할 수 있습니다. email@gmail.com 접미사가없고 hd 가없는 경우 Google은 신뢰할 수 없으며 사용자를 확인하기 위해 비밀번호 또는 다른 질문 방법을 사용하는 것이 좋습니다. email_verfied 는 Google 계정이 생성 될 때 Google이 처음에 사용자를 확인 email_verfied true 일 수도 있지만 이후 타사 이메일 계정의 소유권이 변경되었을 수 있습니다.

Check if the Google account is already present in your authentication system

Check whether either of the following conditions are true:

  • The Google Account ID, found in the assertion's sub field, is in your user database.
  • The email address in the assertion matches a user in your user database.

If either condition is true, the user has already signed up. In that case, return a response like the following:

HTTP/1.1 200 Success
Content-Type: application/json;charset=UTF-8

{
  "account_found":"true",
}

If neither the Google Account ID nor the email address specified in the assertion matches a user in your database, the user hasn't signed up yet. In this case, your token exchange endpoint needs to reply with a HTTP 404 error that specifies "account_found": "false", as in the following example:

HTTP/1.1 404 Not found
Content-Type: application/json;charset=UTF-8

{
  "account_found":"false",
}

Handle automatic linking (get intent)

After the user gives consent to access their Google profile, Google sends a request that contains a signed assertion of the Google user's identity. The assertion contains information that includes the user's Google Account ID, name, and email address. The token exchange endpoint configured for your project handles that request.

If the corresponding Google Account is already present in your authentication system, your token exchange endpoint returns a token for the user. If the Google Account doesn't match an existing user, your token exchange endpoint returns a linking_error error and optional login_hint.

The request has the following form:

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

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=get&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

Your token exchange endpoint must be able to handle the following parameters:

Token endpoint parameters
intent For these requests, the value of this parameter is get.
grant_type The type of token being exchanged. For these requests, this parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address.
scope Optional: Any scopes that you've configured Google to request from users.
client_id The client ID you assigned to Google.
client_secret The client secret you assigned to Google.

To respond to the get intent requests, your token exchange endpoint must perform the following steps:

  • Validate and decode the JWT assertion.
  • Check if the Google account is already present in your authentication system.
JWT 어설 션 유효성 검사 및 디코딩

해당 언어에 대한 JWT 디코딩 라이브러리를 사용하여 JWT 어설 션의 유효성을 검사하고 디코딩 할 수 있습니다 . JWK 또는 PEM 형식으로 제공되는 Google의 공개 키를 사용하여 토큰의 서명을 확인합니다.

디코딩 될 때 JWT 어설 션은 다음 예제와 같습니다.

{
  "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
}

토큰의 서명을 확인하는 것 외에도 어설 션의 발급자 ( iss 필드)가 https://accounts.google.com 이고 대상 ( aud 필드)이 할당 된 클라이언트 ID이며 토큰이 만료되지 않았는지 ( exp 들).

email , email_verifiedhd 필드를 사용하여 Google이 이메일 주소를 호스팅하고 권한이 있는지 확인할 수 있습니다. Google이 권한이있는 경우 사용자는 현재 합법적 인 계정 소유자로 알려져 있으며 비밀번호 또는 기타 질문 방법을 건너 뛸 수 있습니다. 그렇지 않으면 이러한 방법을 사용하여 연결하기 전에 계정을 확인할 수 있습니다.

Google이 권위있는 사례 :

  • email 에는 @gmail.com 접미사가 있으며 이는 Gmail 계정입니다.
  • email_verified 가 true이고 hd 가 설정되어있는 G Suite 계정입니다.

사용자는 Gmail 또는 G Suite를 사용하지 않고 Google 계정에 등록 할 수 있습니다. email@gmail.com 접미사가없고 hd 가없는 경우 Google은 신뢰할 수 없으며 사용자를 확인하기 위해 비밀번호 또는 다른 질문 방법을 사용하는 것이 좋습니다. email_verfied 는 Google 계정이 생성 될 때 Google이 처음에 사용자를 확인 email_verfied true 일 수도 있지만 이후 타사 이메일 계정의 소유권이 변경되었을 수 있습니다.

Check if the Google account is already present in your authentication system

Check whether either of the following conditions are true:

  • The Google Account ID, found in the assertion's sub field, is in your user database.
  • The email address in the assertion matches a user in your user database.

If an account is found for the user, issue an access token and return the values in a JSON object in the body of your HTTPS response, like in the following example:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

In some cases, account linking based on ID token might fail for the user. If it does so for any reason, your token exchange endpoint needs to reply with a HTTP 401 error that specifies error=linking_error, as the following example shows:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

When Google receives a 401 error response with linking_error, Google sends the user to your authorization endpoint with login_hint as a parameter. The user completes account linking using the OAuth linking flow in their browser.

Handle account creation via Google Sign-In (create intent)

When a user needs to create an account on your service, Google makes a request to your token exchange endpoint that specifies intent=create.

The request has the following form:

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

response_type=token&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=SCOPES&intent=create&assertion=JWT&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

Your token exchange endpoint must able to handle the following parameters:

Token endpoint parameters
intent For these requests, the value of this parameter is create.
grant_type The type of token being exchanged. For these requests, this parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address.
client_id The client ID you assigned to Google.
client_secret The client secret you assigned to Google.

The JWT within the assertion parameter contains the user's Google Account ID, name, and email address, which you can use to create a new account on your service.

To respond to the create intent requests, your token exchange endpoint must perform the following steps:

  • Validate and decode the JWT assertion.
  • Validate user information and create new account.
JWT 어설 션 유효성 검사 및 디코딩

해당 언어에 대한 JWT 디코딩 라이브러리를 사용하여 JWT 어설 션의 유효성을 검사하고 디코딩 할 수 있습니다 . JWK 또는 PEM 형식으로 제공되는 Google의 공개 키를 사용하여 토큰의 서명을 확인합니다.

디코딩 될 때 JWT 어설 션은 다음 예제와 같습니다.

{
  "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
}

토큰의 서명을 확인하는 것 외에도 어설 션의 발급자 ( iss 필드)가 https://accounts.google.com 이고 대상 ( aud 필드)이 할당 된 클라이언트 ID이며 토큰이 만료되지 않았는지 ( exp 들).

email , email_verifiedhd 필드를 사용하여 Google이 이메일 주소를 호스팅하고 권한이 있는지 확인할 수 있습니다. Google이 권한이있는 경우 사용자는 현재 합법적 인 계정 소유자로 알려져 있으며 비밀번호 또는 기타 질문 방법을 건너 뛸 수 있습니다. 그렇지 않으면 이러한 방법을 사용하여 연결하기 전에 계정을 확인할 수 있습니다.

Google이 권위있는 사례 :

  • email 에는 @gmail.com 접미사가 있으며 이는 Gmail 계정입니다.
  • email_verified 가 true이고 hd 가 설정되어있는 G Suite 계정입니다.

사용자는 Gmail 또는 G Suite를 사용하지 않고 Google 계정에 등록 할 수 있습니다. email@gmail.com 접미사가없고 hd 가없는 경우 Google은 신뢰할 수 없으며 사용자를 확인하기 위해 비밀번호 또는 다른 질문 방법을 사용하는 것이 좋습니다. email_verfied 는 Google 계정이 생성 될 때 Google이 처음에 사용자를 확인 email_verfied true 일 수도 있지만 이후 타사 이메일 계정의 소유권이 변경되었을 수 있습니다.

Validate user information and create new account

Check whether either of the following conditions are true:

  • The Google Account ID, found in the assertion's sub field, is in your user database.
  • The email address in the assertion matches a user in your user database.

If either condition is true, prompt the user to link their existing account with their Google Account. To do so, respond to the request with an HTTP 401 error that specifies error=linking_error and gives the user's email address as the login_hint. The following is a sample response:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

When Google receives a 401 error response with linking_error, Google sends the user to your authorization endpoint with login_hint as a parameter. The user completes account linking using the OAuth linking flow in their browser.

If neither condition is true, create a new user account with the information provided in the JWT. New accounts don't typically have a password set. It's recommended that you add Google Sign-In to other platforms to enable users to log in with Google across the surfaces of your application. Alternatively, you can email the user a link that starts your password recovery flow to allow the user to set a password to sign in on other platforms.

When the creation is completed, issue an access token and return the values in a JSON object in the body of your HTTPS response, like in the following example:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

Google API 클라이언트 ID 가져오기

계정 연결 등록 과정 중에 Google API 클라이언트 ID를 제공해야 합니다.

OAuth 연결 단계를 완료하는 동안 만든 프로젝트를 사용하여 API 클라이언트 ID를 가져옵니다. 그러려면 다음 단계를 완료하세요.

  1. Google API 콘솔사용자 인증 정보 페이지를 엽니다.
  2. Google API 프로젝트를 만들거나 선택합니다.

    프로젝트에 웹 애플리케이션 유형의 클라이언트 ID가 없으면 사용자 인증 정보 만들기 > OAuth 클라이언트 ID를 클릭하여 클라이언트 ID를 만듭니다. 승인된 자바스크립트 원본 상자에 사이트의 도메인을 포함해야 합니다. 로컬 테스트 또는 개발을 실행할 때 승인된 자바스크립트 원본 필드에 http://localhosthttp://localhost:<port_number>를 모두 추가해야 합니다.

구현 확인

You can validate your implementation by using the OAuth 2.0 Playground tool.

In the tool, do the following steps:

  1. Click Configuration to open the OAuth 2.0 Configuration window.
  2. In the OAuth flow field, select Client-side.
  3. In the OAuth Endpoints field, select Custom.
  4. Specify your OAuth 2.0 endpoint and the client ID you assigned to Google in the corresponding fields.
  5. In the Step 1 section, don't select any Google scopes. Instead, leave this field blank or type a scope valid for your server (or an arbitrary string if you don't use OAuth scopes). When you're done, click Authorize APIs.
  6. In the Step 2 and Step 3 sections, go through the OAuth 2.0 flow and verify that each step works as intended.

You can validate your implementation by using the Google Account Linking Demo tool.

In the tool, do the following steps:

  1. Click the Sign-in with Google button.
  2. Choose the account you'd like to link.
  3. Enter the service ID.
  4. Optionally enter one or more scopes that you will request access for.
  5. Click Start Demo.
  6. When prompted, confirm that you may consent and deny the linking request.
  7. Confirm that you are redirected to your platform.