개요
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">
检查现有用户账号(检查 intent)
在用户同意访问其 Google 个人资料后,Google 会发送 请求,其中包含 Google 用户身份的已签名断言。通过 断言包含的信息包括用户的 Google 账号 ID、 姓名和电子邮件地址为您的 Google Cloud 控制台配置的令牌交换端点 项目处理该请求。
如果您的身份验证中已有相应的 Google 账号
系统时,您的令牌交换端点会返回 account_found=true
。如果
Google 账号与现有用户不匹配,您的令牌交换端点
返回“HTTP 404 Not Found”错误以及 account_found=false
。
请求的格式如下:
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
您的令牌交换端点必须能够处理以下参数:
令牌端点参数 | |
---|---|
intent |
对于这些请求,此参数的值为
check 。 |
grant_type |
所交换的令牌的类型。对于这类请求
参数的值为 urn:ietf:params:oauth:grant-type:jwt-bearer 。 |
assertion |
一个 JSON Web 令牌 (JWT),提供 Google 用户身份。JWT 包含的信息包括用户 Google 账号 ID、姓名和电子邮件地址。 |
client_id |
您分配给 Google 的客户 ID。 |
client_secret |
您分配给 Google 的客户端密钥。 |
如需响应 check
intent 请求,您的令牌交换端点必须执行以下步骤:
- 验证和解码 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 账号
请检查以下任一条件是否成立:
- Google 账号 ID(可在断言的
sub
字段中找到)位于您的用户中 数据库。 - 断言中的电子邮件地址与用户数据库中的用户匹配。
如果满足上述任一条件,则表明用户已注册。在这种情况下 返回如下所示的响应:
HTTP/1.1 200 Success Content-Type: application/json;charset=UTF-8 { "account_found":"true", }
如果 Google 账号 ID 和
断言与您的数据库中的用户匹配,该用户尚未注册。在
在这种情况下,您的令牌交换端点需要返回 HTTP 404 错误
指定 "account_found": "false"
,如以下示例所示:
HTTP/1.1 404 Not found Content-Type: application/json;charset=UTF-8 { "account_found":"false", }
处理自动链接(获取 intent)
在用户同意访问其 Google 个人资料后,Google 会发送 请求,其中包含 Google 用户身份的已签名断言。通过 断言包含的信息包括用户的 Google 账号 ID、 姓名和电子邮件地址为您的 Google Cloud 控制台配置的令牌交换端点 项目处理该请求。
如果您的身份验证中已有相应的 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 |
一个 JSON Web 令牌 (JWT),提供 Google 用户身份。JWT 包含的信息包括用户 Google 账号 ID、姓名和电子邮件地址。 |
scope |
可选:您已将 Google 配置为向其请求访问权限的任何范围 用户。 |
client_id |
您分配给 Google 的客户 ID。 |
client_secret |
您分配给 Google 的客户端密钥。 |
如需响应 get
intent 请求,您的令牌交换端点必须执行以下步骤:
- 验证和解码 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 账号
请检查以下任一条件是否成立:
- Google 账号 ID(可在断言的
sub
字段中找到)位于您的用户中 数据库。 - 断言中的电子邮件地址与用户数据库中的用户匹配。
如果找到了用户的账号,请发出访问令牌,并在 HTTPS 响应正文的 JSON 对象中返回相应值,如以下示例所示:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "refresh_token": "REFRESH_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
在某些情况下,基于 ID 令牌的账号关联可能会失败。如果
因为任何原因,您的令牌交换端点都需要以 HTTP 响应
指定 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 关联流程完成账号关联。
Google 로그인을 통한 계정 생성 처리 (인텐트 만들기)
사용자가 서비스에서 계정을 만들어야 하는 경우 Google에서 요청을 합니다.
intent=create
를 지정하는 토큰 교환 엔드포인트에 추가해야 합니다.
요청의 형식은 다음과 같습니다.
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
토큰 교환 엔드포인트는 다음 매개변수를 처리할 수 있어야 합니다.
토큰 엔드포인트 매개변수 | |
---|---|
intent |
이러한 요청에서 이 매개변수의 값은 create 입니다. |
grant_type |
교환되는 토큰의 유형입니다. 이러한 요청의 경우
매개변수의 값은 urn:ietf:params:oauth:grant-type:jwt-bearer 입니다. |
assertion |
Google API의 서명된 어설션을 제공하는 JSON 웹 토큰 (JWT)입니다. 사용자 ID입니다. JWT에는 사용자의 Google 계정 ID, 이름, 이메일 주소 |
client_id |
Google에 할당한 클라이언트 ID입니다. |
client_secret |
Google에 할당한 클라이언트 비밀번호입니다. |
assertion
매개변수 내 JWT에는 사용자의 Google 계정 ID가 포함됩니다.
새 계정을 만드는 데 사용할 수 있는 이름, 이메일 주소
있습니다.
create
인텐트 요청에 응답하려면 토큰 교환 엔드포인트가 다음 단계를 수행해야 합니다.
- JWT 어설션을 검증하고 디코딩합니다.
- 사용자 정보를 확인하고 새 계정을 만듭니다.
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자의 소유권은
이메일 계정이 변경되었을 수 있습니다.
사용자 정보 확인 및 새 계정 만들기
다음 조건 중 하나가 충족되는지 확인합니다.
- 어설션의
sub
필드에서 찾을 수 있는 Google 계정 ID는 사용자에 있습니다. 데이터베이스입니다. - 어설션의 이메일 주소가 사용자 데이터베이스의 사용자와 일치합니다.
두 조건 중 하나라도 충족되면 사용자에게 기존 계정을 연결하라는 메시지를 표시합니다.
로그인 이렇게 하려면 HTTP 401 오류로 요청에 응답합니다.
- error=linking_error
를 지정하고 사용자의 이메일 주소를
login_hint
입니다. 다음은 샘플 응답입니다.
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 연결 흐름을 사용하여 계정 연결을 완료합니다.
두 조건이 모두 충족되지 않는 경우 다음 정보를 사용하여 새 사용자 계정을 만듭니다. 확인할 수 있습니다 일반적으로 새 계정에는 비밀번호가 설정되지 않습니다. 그것은 다른 플랫폼에 Google 로그인을 추가하여 Google 계정으로 로그인할 수 있습니다. 또는 사용자에게 비밀번호 복구 절차를 시작하는 링크를 이메일로 전송하여 사용자가 다른 플랫폼에서 로그인하기 위한 비밀번호를 설정하도록 요청할 수 있습니다.
생성이 완료되면 액세스 토큰을 발급합니다. 새로고침 토큰을 만들고 JSON 객체의 값을 반환하며 HTTP 응답의 본문을 입력하세요. <ph type="x-smartling-placeholder">
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "refresh_token": "REFRESH_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }</ph>
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 출처 필드에 추가합니다.
구현 확인
您可以使用 OAuth 2.0 Playground 工具验证您的实现。
在该工具中,执行以下步骤:
- 点击配置 以打开 OAuth 2.0 配置窗口。
- 在 OAuth flow 字段中,选择 Client-side(客户端)。
- 在 OAuth 端点字段中,选择自定义。
- 在相应字段中指定您的 OAuth 2.0 端点和您分配给 Google 的客户端 ID。
- 在第 1 步部分,不要选择任何 Google 范围。请将此字段留空或输入对服务器有效的范围(如果您不使用 OAuth 范围,则可以输入任意字符串)。完成后,点击授权 API。
- 在 Step 2 和 Step 3 部分中,完成 OAuth 2.0 流程,并验证每个步骤是否按预期运行。
您可以使用 Google 账号关联演示版工具验证您的实现。
在该工具中,执行以下步骤:
- 点击使用 Google 账号登录按钮。
- 选择您要关联的账号。
- 输入服务 ID。
- (可选)输入您要请求访问权限的一个或多个范围。
- 点击开始演示。
- 当系统提示时,请确认您同意或拒绝关联请求。
- 确认您已被重定向到您的平台。