개요
OAuth 기반 Google 로그인 간소화된 연결은 OAuth 연결. 이렇게 하면 Google 사용자 및 계정 생성도 가능하므로 사용자는 자신의 Google 계정을 사용하여 서비스에 새 계정을 만들 수 있습니다.
OAuth 및 Google 로그인으로 계정을 연결하려면 다음 일반 단계를 따르세요. 단계:
- 먼저 사용자에게 Google 프로필 액세스에 동의해 달라고 요청합니다.
- 사용자 프로필의 정보를 사용하여 사용자 계정이 존재하는지 확인합니다.
- 기존 사용자의 경우 계정을 연결합니다.
- 인증 시스템에서 Google 사용자와 일치하는 항목을 찾을 수 없는 경우 Google에서 받은 ID 토큰을 검증합니다. 그런 다음 이 거래 조건을 기반으로 ID 토큰에 포함된 프로필 정보에서 찾을 수 있습니다.
그림 1. 간소화된 연결을 통해 사용자 휴대전화에서 계정 연결
간소화된 연결을 위한 요구사항
- 기본 웹 OAuth 연결 흐름을 구현합니다. 서비스에서 OAuth 2.0 호환을 지원해야 합니다. 승인 및 토큰 교환 엔드포인트가 있습니다.
- 토큰 교환 엔드포인트는 JSON 웹 토큰 (JWT) 어설션을 지원하고
check
,create
,get
인텐트를 구현해야 합니다.
OAuth 서버 구현
토큰 교환 엔드포인트는 check
, create
, get
인텐트를 지원해야 합니다. 아래는 계정 연결 흐름을 통해 완료된 단계를 보여주며, 서로 다른 인텐트가 호출되는 시점을 나타냅니다.
- 인증 시스템에 사용자의 계정이 있나요? (사용자가 '예' 또는 '아니요'를 선택하여 결정)
<ph type="x-smartling-placeholder">
- </ph>
- 예 : 사용자가 플랫폼에 로그인할 때 자신의 Google 계정과 연결된 이메일을 사용하나요? (사용자가 '예' 또는 '아니요'를 선택하여 결정)
<ph type="x-smartling-placeholder">
- </ph>
- 예 : 사용자의 인증 시스템에 일치하는 계정이 있나요? (확인을 위해
check intent
가 호출됨) <ph type="x-smartling-placeholder">- </ph>
- 예 : get 인텐트가 성공적으로 반환되면
get intent
가 호출되고 계정이 연결됩니다. - 아니요 : 새 계정을 만드시겠습니까? (사용자가 '예' 또는 '아니요'를 선택하여 결정)
<ph type="x-smartling-placeholder">
- </ph>
- 예 : 인텐트 만들기가 성공적으로 반환되면
create intent
가 호출되고 계정이 연결됩니다. - 아니요 : 웹 OAuth 흐름이 트리거되고 사용자가 브라우저로 이동되며 다른 이메일로 연결할 수 있는 옵션이 제공됩니다.
- 예 : 인텐트 만들기가 성공적으로 반환되면
- 예 : get 인텐트가 성공적으로 반환되면
- 아니요 : 웹 OAuth 흐름이 트리거되고 사용자가 브라우저로 이동되며 다른 이메일로 연결할 수 있는 옵션이 제공됩니다.
- 예 : 사용자의 인증 시스템에 일치하는 계정이 있나요? (확인을 위해
- 아니요 : 사용자의 인증 시스템에 일치하는 계정이 있나요? (확인을 위해
check intent
가 호출됨) <ph type="x-smartling-placeholder">- </ph>
- 예 : get 인텐트가 성공적으로 반환되면
get intent
가 호출되고 계정이 연결됩니다. - NO : 인텐트 만들기가 성공적으로 반환되면
create intent
가 호출되고 계정이 연결됩니다.
- 예 : get 인텐트가 성공적으로 반환되면
- 예 : 사용자가 플랫폼에 로그인할 때 자신의 Google 계정과 연결된 이메일을 사용하나요? (사용자가 '예' 또는 '아니요'를 선택하여 결정)
<ph type="x-smartling-placeholder">
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-디코딩 라이브러리를 참조하세요. 사용 Google의 공개 키( JWK 또는 PEM 형식을 사용하여 토큰의 서명을 받습니다.
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_verified
, hd
필드를 사용하면
Google은 이메일 주소를 호스팅하고 이에 대한 권한이 있습니다. Google이
사용자가 현재 합법적인 계정 소유자로 알려진 권한
비밀번호나 다른 본인 확인 요청을 건너뛸 수 있습니다. 그렇지 않으면
연결하기 전에 계정을 확인하는 데 사용할 수 있습니다.
Google이 신뢰할 수 있는 케이스:
email
의 접미사는@gmail.com
입니다. 이 계정은 Gmail 계정입니다.email_verified
이(가) true이고hd
이(가) 설정되어 있습니다. 이는 G Suite 계정입니다.
사용자는 Gmail 또는 G Suite를 사용하지 않고도 Google 계정에 등록할 수 있습니다. 날짜
email
에 @gmail.com
서픽스가 포함되어 있지 않고 hd
이(가) 없습니다. Google은 포함되지 않습니다.
신뢰할 수 있는 비밀번호나 다른 본인 확인 방법을 사용하여
있습니다. Google에서 처음에 확인했으므로 email_verified
도 true일 수 있습니다.
사용자에게 양도할 수 있지만 제3자의 소유권은
이메일 계정이 변경되었을 수 있습니다.
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", }
자동 연결 처리 (인텐트 가져오기)
사용자가 Google 프로필 액세스에 동의하면 Google에서는 Google 사용자 ID의 서명된 어설션이 포함된 요청입니다. 이 어설션에는 사용자의 Google 계정 ID, 사용자 이름, 이메일 주소 등이 포함되어 있습니다 해당 요청을 처리합니다
해당 Google 계정이 이미 인증에 있는 경우
토큰 교환 엔드포인트가 사용자의 토큰을 반환합니다. 만약
Google 계정이 기존 사용자와 일치하지 않습니다(토큰 교환 엔드포인트).
linking_error
오류와 선택적 login_hint
를 반환합니다.
요청의 형식은 다음과 같습니다.
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
토큰 교환 엔드포인트는 다음 매개변수를 처리할 수 있어야 합니다.
토큰 엔드포인트 매개변수 | |
---|---|
intent |
이러한 요청에서 이 매개변수의 값은 get 입니다. |
grant_type |
교환되는 토큰의 유형입니다. 이러한 요청의 경우
매개변수의 값은 urn:ietf:params:oauth:grant-type:jwt-bearer 입니다. |
assertion |
Google API의 서명된 어설션을 제공하는 JSON 웹 토큰 (JWT)입니다. 사용자 ID입니다. JWT에는 사용자의 Google 계정 ID, 이름, 이메일 주소 |
scope |
선택사항: Google이 요청하도록 구성한 모든 범위 있습니다. |
client_id |
Google에 할당한 클라이언트 ID입니다. |
client_secret |
Google에 할당한 클라이언트 비밀번호입니다. |
get
인텐트 요청에 응답하려면 토큰 교환 엔드포인트가 다음 단계를 수행해야 합니다.
- JWT 어설션을 검증하고 디코딩합니다.
- 해당 Google 계정이 인증 시스템에 이미 있는지 확인합니다.
JWT 어설션 검증 및 디코딩
다음을 사용하여 JWT 어설션을 검증하고 디코딩할 수 있습니다. 해당 언어의 JWT-디코딩 라이브러리를 참조하세요. 사용 Google의 공개 키( JWK 또는 PEM 형식을 사용하여 토큰의 서명을 받습니다.
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_verified
, hd
필드를 사용하면
Google은 이메일 주소를 호스팅하고 이에 대한 권한이 있습니다. Google이
사용자가 현재 합법적인 계정 소유자로 알려진 권한
비밀번호나 다른 본인 확인 요청을 건너뛸 수 있습니다. 그렇지 않으면
연결하기 전에 계정을 확인하는 데 사용할 수 있습니다.
Google이 신뢰할 수 있는 케이스:
email
의 접미사는@gmail.com
입니다. 이 계정은 Gmail 계정입니다.email_verified
이(가) true이고hd
이(가) 설정되어 있습니다. 이는 G Suite 계정입니다.
사용자는 Gmail 또는 G Suite를 사용하지 않고도 Google 계정에 등록할 수 있습니다. 날짜
email
에 @gmail.com
서픽스가 포함되어 있지 않고 hd
이(가) 없습니다. Google은 포함되지 않습니다.
신뢰할 수 있는 비밀번호나 다른 본인 확인 방법을 사용하여
있습니다. Google에서 처음에 확인했으므로 email_verified
도 true일 수 있습니다.
사용자에게 양도할 수 있지만 제3자의 소유권은
이메일 계정이 변경되었을 수 있습니다.
Google 계정이 인증 시스템에 이미 있는지 확인
다음 조건 중 하나가 충족되는지 확인합니다.
- 어설션의
sub
필드에서 찾을 수 있는 Google 계정 ID는 사용자에 있습니다. 데이터베이스입니다. - 어설션의 이메일 주소가 사용자 데이터베이스의 사용자와 일치합니다.
사용자의 계정이 발견되면 액세스 토큰을 발급하고 다음 예와 같이 HTTPS 응답 본문에 JSON 객체로 값을 반환합니다.
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "refresh_token": "REFRESH_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
경우에 따라 사용자가 ID 토큰을 기반으로 한 계정 연결에 실패할 수 있습니다. 만약
그렇게 하면 토큰 교환 엔드포인트는
다음 예와 같이 error=linking_error
를 지정하는 401 오류
HTTP/1.1 401 Unauthorized Content-Type: application/json;charset=UTF-8 { "error":"linking_error", "login_hint":"foo@bar.com" }
Google이 linking_error
와 함께 401 오류 응답을 수신하면
login_hint
를 매개변수로 사용하여 사용자를 승인 엔드포인트에 보냅니다. 이
사용자가 브라우저에서 OAuth 연결 흐름을 사용하여 계정 연결을 완료합니다.
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-디코딩 라이브러리를 참조하세요. 사용 Google의 공개 키( JWK 또는 PEM 형식을 사용하여 토큰의 서명을 받습니다.
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_verified
, hd
필드를 사용하면
Google은 이메일 주소를 호스팅하고 이에 대한 권한이 있습니다. Google이
사용자가 현재 합법적인 계정 소유자로 알려진 권한
비밀번호나 다른 본인 확인 요청을 건너뛸 수 있습니다. 그렇지 않으면
연결하기 전에 계정을 확인하는 데 사용할 수 있습니다.
Google이 신뢰할 수 있는 케이스:
email
의 접미사는@gmail.com
입니다. 이 계정은 Gmail 계정입니다.email_verified
이(가) true이고hd
이(가) 설정되어 있습니다. 이는 G Suite 계정입니다.
사용자는 Gmail 또는 G Suite를 사용하지 않고도 Google 계정에 등록할 수 있습니다. 날짜
email
에 @gmail.com
서픽스가 포함되어 있지 않고 hd
이(가) 없습니다. Google은 포함되지 않습니다.
신뢰할 수 있는 비밀번호나 다른 본인 확인 방법을 사용하여
있습니다. Google에서 처음에 확인했으므로 email_verified
도 true일 수 있습니다.
사용자에게 양도할 수 있지만 제3자의 소유권은
이메일 계정이 변경되었을 수 있습니다.
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 refresh 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", "refresh_token": "REFRESH_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
Google API 클라이언트 ID 가져오기
계정 연결 등록 과정에서 Google API 클라이언트 ID를 제공해야 합니다.
OAuth 연결 단계를 완료하면서 생성한 프로젝트를 사용하여 API 클라이언트 ID를 가져옵니다. 그러려면 다음 단계를 완료하세요.
- 사용자 인증 정보 페이지의 사용자 인증 정보 페이지를 Google API 콘솔.
Google API 프로젝트를 만들거나 선택합니다.
프로젝트에 웹 애플리케이션 유형에 대한 클라이언트 ID가 없는 경우 사용자 인증 정보 만들기 > OAuth 클라이언트 ID를 사용하여 OAuth 클라이언트 ID를 만듭니다. 다음 항목을 포함해야 합니다. 사이트의 도메인을 승인된 JavaScript 출처 상자에 입력합니다. GCP Console에서 로컬 테스트 또는 개발의 경우
http://localhost
및http://localhost:<port_number>
를 승인된 JavaScript 출처 필드에 추가합니다.
구현 확인
You can validate your implementation by using the OAuth 2.0 Playground tool.
In the tool, do the following steps:
- Click Configuration to open the OAuth 2.0 Configuration window.
- In the OAuth flow field, select Client-side.
- In the OAuth Endpoints field, select Custom.
- Specify your OAuth 2.0 endpoint and the client ID you assigned to Google in the corresponding fields.
- 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.
- 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:
- Click the Sign-in with Google button.
- Choose the account you'd like to link.
- Enter the service ID.
- Optionally enter one or more scopes that you will request access for.
- Click Start Demo.
- When prompted, confirm that you may consent and deny the linking request.
- Confirm that you are redirected to your platform.