帳戶連結會使用業界標準的 OAuth 2.0 隱含和授權碼流程。您的服務必須支援符合 OAuth 2.0 標準的授權和權杖交換端點。
在隐式流程中,Google 会在用户的浏览器中打开您的授权端点。成功登录后,您将向 Google 返回一个长期访问令牌。现在,此访问令牌会包含在 Google 发送的每个请求中。
在授权代码流程中,您需要两个端点:
授权端点,用于向尚未登录的用户显示登录界面。授权端点还会创建一个短期授权代码,以记录用户对所请求访问权限的同意情况。
令牌交换端点,负责两种类型的交换:
- 使用授权代码换取长期有效的刷新令牌和短期有效的访问令牌。当用户完成账号关联流程时,就会发生此交换。
- 将长期有效的刷新令牌换成短期有效的访问令牌。当 Google 需要新的访问令牌(因为现有访问令牌已过期)时,就会发生这种交换。
选择 OAuth 2.0 流程
虽然隐式流程更易于实现,但 Google 建议通过隐式流程签发的访问令牌永不过期。这是因为,在隐式流程中,令牌过期后,系统会强制用户重新关联其账号。如果您出于安全考虑需要令牌过期,我们强烈建议您改用授权码流程。
设计准则
本部分介绍了您为 OAuth 关联流程托管的用户屏幕的设计要求和建议。在 Google 应用调用该 API 后,您的平台会向用户显示登录 Google 页面和账号关联意见征求界面。同意关联账号后,系统会将用户重定向回 Google 的应用。
要求
- 您必须说明用户的账号将与 Google 相关联,而非 Google Home 或 Google 助理等特定 Google 产品相关联。
建议
建议您执行以下操作:
显示 Google 的隐私权政策。在同意屏幕上添加指向 Google 隐私权政策的链接。
要共享的数据。使用清晰简洁的语言告知用户 Google 需要哪些用户数据以及原因。
添加醒目的号召性用语。在用户同意页面上提供明确的号召性用语,例如“同意并关联”。这是因为用户需要了解他们需要与 Google 分享哪些数据才能关联账号。
可以取消。为用户提供返回或取消链接的途径,如果用户选择不进行关联。
明确的登录流程。确保用户有明确的 Google 账号登录方法,例如用户名和密码字段或使用 Google 账号登录。
能够解除关联。提供一种可让用户解除关联的机制,例如指向您平台上账号设置的网址。或者,您也可以添加指向 Google 账号的链接,以便用户管理其关联的账号。
能够更改用户账号。建议用户切换账号的方法。如果用户通常拥有多个账号,这种做法尤为有益。
- 如果用户必须关闭意见征求界面才能切换账号,请向 Google 发送可恢复的错误,以便用户可以使用 OAuth 关联和隐式流程登录所需的账号。
添加您的徽标。在意见征求页面上显示您的公司徽标。 按照您的样式准则放置徽标。如果您还想显示 Google 的徽标,请参阅徽标和商标。
创建项目
如需创建使用账号关联的项目,请执行以下操作:
- 点击 Create project。
- 输入名称或接受生成的建议。
- 确认或修改所有剩余字段。
- 点击创建。
如需查看项目 ID,请执行以下操作:
- 在着陆页的表格中找到您的项目。项目 ID 会显示在 ID 列中。
配置 OAuth 权限请求页面
Google 账号关联流程包含一个权限请求页面,该页面会告知用户哪个应用在请求访问其数据、请求访问哪些类型的数据,以及适用的条款。您需要先配置 OAuth 权限请求页面,然后才能生成 Google API 客户端 ID。
- 打开 Google API 控制台的 OAuth 同意屏幕页面。
- 如果出现提示,请选择您刚刚创建的项目。
在“OAuth 同意屏幕”页面上,填写表单,然后点击“保存”按钮。
应用名称:征求用户同意的应用的名称。名称应准确反映您的应用,并与用户在其他位置看到的应用名称保持一致。应用名称将显示在账号关联权限请求界面上。
应用徽标:权限请求页面上显示的一张图片,用以让用户认出您的应用。徽标会显示在账号关联权限请求页面和账号设置中
支持电子邮件地址:供用户就其同意问题与您联系。
Google API 的范围:借助范围,您的应用可以访问用户的非公开 Google 数据。对于 Google 账号关联使用情形,默认范围(电子邮件地址、个人资料、openid)就足够了,您无需添加任何敏感范围。一般来说,最佳做法是在需要访问权限时逐步请求权限范围,而不是提前请求。了解详情。
已获授权的网域:为了保护您和您的用户,Google 只允许使用 OAuth 进行身份验证的应用使用已获授权的网域。应用的链接必须托管在已获授权的网域上。了解详情。
应用首页链接:应用的首页。必须托管在已获授权的网域上。
应用隐私权政策链接:显示在 Google 账号关联意见征求界面上。必须托管在已获授权的网域上。
应用服务条款链接(可选):必须托管在已获授权的网域上。
图 1. 虚构应用 Tunery 的 Google 账号关联意见征求界面
查看“验证状态”,如果您的应用需要验证,请点击“提交以供验证”按钮,提交应用以供验证。如需了解详情,请参阅 OAuth 验证要求。
實作 OAuth 伺服器
授權碼流程的 OAuth 2.0 伺服器實作包含 服務透過 HTTPS 提供第一個端點 是授權端點,負責尋找或取得 徵得使用者同意並授予資料存取權授權端點會顯示 登入使用者介面,供尚未登入的使用者查看,且將同意 所要求的存取權第二個端點是權杖交換端點 用於取得加密字串 (稱為「權杖」),藉此授權使用者 存取您的服務。
當 Google 應用程式需要呼叫服務的其中一個 API 時,Google 會使用 這些端點都會一起取得權限,以便使用者呼叫這些 API 管理。
由 Google 發起的 OAuth 2.0 授權碼流程工作階段, 下列流程:
- Google 會在使用者的瀏覽器中開啟授權端點。如果流程 透過純語音裝置啟動動作,則 Google 將 到手機上
- 使用者登入後 (如果尚未登入),並將權限授予 Google 透過您的 API 存取他們的資料 (如果尚未授予權限)。
- 您的服務會建立授權碼,並傳回 Google。待辦 因此,請透過授權碼將使用者的瀏覽器重新導向回 Google 附加在要求中
- Google 將授權碼傳送至權杖交換端點 驗證程式碼的真實性,並傳回存取權杖和 更新權杖。存取權杖是服務 以憑證存取 API。更新權杖存在長期 憑證,可供 Google 儲存,用於取得新的存取權杖 過期。
- 使用者完成帳戶連結流程後, 來自 Google 的要求會包含存取權杖。
處理授權要求
使用 OAuth 2.0 授權碼執行帳戶連結時 流程時,Google 會透過以下要求將使用者傳送到您的授權端點 包含下列參數:
| 授權端點參數 | |
|---|---|
client_id |
您指派給 Google 的用戶端 ID。 |
redirect_uri |
您傳送回應到這項要求的網址。 |
state |
傳回給 Google 的記帳金額,值維持不變 重新導向 URI |
scope |
選用:一組以空格分隔的範圍字串,指定 也就是 Google 要求授權的資料 |
response_type |
要在回應中傳回的值類型。針對 OAuth 2.0
授權碼流程,回應類型一律為 code。
|
user_locale |
中的 Google 帳戶語言設定 RFC5646 格式,用來將內容翻譯成使用者偏好的語言。 |
舉例來說,如果您的授權端點位於
https://myservice.example.com/auth,要求可能如下所示:
GET https://myservice.example.com/auth?client_id=GOOGLE_CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE_STRING&scope=REQUESTED_SCOPES&response_type=code&user_locale=LOCALE
如要讓授權端點處理登入要求,請按照下列步驟操作: 步驟:
- 確認
client_id與您指派給 Google 的用戶端 ID 相符,且redirect_uri與 Google 為您的服務提供的重新導向網址相符。這些檢查至關重要 存取非預期或設定錯誤的用戶端應用程式。如果跨平台支援 OAuth 2.0 流程,也可以確認response_type是code。 - 檢查使用者是否已登入您的服務。如果使用者未登入, 完成服務的登入或註冊流程。
- 產生授權代碼,讓 Google 用來存取您的 API。 授權碼可以是任何字串值,但必須不重複 代表使用者、該權杖所屬的用戶端,以及代碼的到期時間 而且您無法憑空猜測您通常會核發授權 驗證碼會在大約 10 分鐘後失效
- 請確認
redirect_uri參數指定的網址包含 以下表單:https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID https://oauth-redirect-sandbox.googleusercontent.com/r/YOUR_PROJECT_ID
- 將使用者的瀏覽器重新導向至
redirect_uri參數。附上 產生的原始值,以及您在重新導向時 方法是附加code和state參數。以下是 結果網址的範例:https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID?code=AUTHORIZATION_CODE&state=STATE_STRING
處理權杖交換要求
服務的權杖交換端點負責兩種權杖 廣告交易平台:
- 交換存取權杖和更新權杖的授權碼
- 交換存取權杖的更新權杖
權杖交換要求包含下列參數:
| 權杖交換端點參數 | |
|---|---|
client_id |
用來識別要求來源為 Google 的字串。此字串必須 在您的系統中註冊為 Google 專屬識別碼。 |
client_secret |
您向 Google 註冊的服務專用密鑰。 |
grant_type |
要交換的權杖類型。這可以是
authorization_code 或 refresh_token。 |
code |
如果 grant_type=authorization_code,這個參數是
Google 從登入或權杖交換收到驗證碼
端點 |
redirect_uri |
如果 grant_type=authorization_code,這個參數是
用於初始授權要求的網址。 |
refresh_token |
如果 grant_type=refresh_token,這個參數是
Google 從您的權杖交換端點收到更新權杖。 |
交換存取權杖和更新權杖的授權碼
使用者登入,且您的授權端點傳回 授權代碼傳送給 Google,Google 會向你的權杖交換要求傳送要求 來交換存取權杖的授權碼 產生下一個符記
在這些要求中,grant_type 的值為 authorization_code,
code 的值是您先前授予的授權碼
Google。以下為
存取權杖和更新權杖的授權碼:
POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET&grant_type=authorization_code&code=AUTHORIZATION_CODE&redirect_uri=REDIRECT_URI
如要交換存取權杖和更新權杖的授權碼,您的
權杖交換端點會執行下列命令來回應 POST 要求:
步驟:
- 驗證
client_id會將要求來源識別為已授權的要求 ,且client_secret符合預期值。 - 請檢查授權碼是否有效且未過期,且 要求中指定的用戶端 ID 與 授權碼。
- 確認
redirect_uri參數指定的網址相同 設為初始授權要求使用的值。 - 如果您無法驗證上述所有條件,請傳回 HTTP
400 「Bad Request」錯誤,內文為
{"error": "invalid_grant"}。 - 否則,請使用授權碼中的使用者 ID 產生重新整理 權杖和存取權杖這些符記可以是任何字串值,但 必須明確代表憑證所屬的用戶端、 另一個使用者如果是存取權杖,也請記下 權杖,通常是在您核發權杖後 1 小時。 重新整理權杖沒有期限。
- 在 HTTPS 回應的內文中傳回下列 JSON 物件:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "refresh_token": "REFRESH_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
Google 會儲存使用者和記錄的存取權杖和更新權杖 存取權杖的到期時間存取權杖到期時,Google 會使用 更新憑證,從權杖交換端點取得新的存取權杖。
交換存取權杖的更新權杖
存取權杖到期時,Google 會傳送要求至您的權杖交換 更新憑證,藉此將更新憑證交換給新的存取權杖。
在這些要求的 grant_type 值為 refresh_token,其值為
refresh_token 是您先前授予的更新權杖值
Google。以下是交換更新權杖的要求範例
定義存取權杖:
POST /token HTTP/1.1 Host: oauth2.example.com Content-Type: application/x-www-form-urlencoded client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET&grant_type=refresh_token&refresh_token=REFRESH_TOKEN
如要將更新權杖換成存取權杖,權杖交換端點
執行下列步驟來回應 POST 要求:
- 驗證
client_id會將要求來源指定為 Google。client_secret與預期值相符 - 驗證更新權杖是否有效,以及 此請求會與更新權杖關聯的用戶端 ID 相符。
- 如果您無法驗證上述所有條件,請傳回 HTTP 400
「Bad Request」錯誤,以
{"error": "invalid_grant"}為主體。 - 否則,請使用更新權杖的使用者 ID 產生存取權 產生下一個符記這些權杖可以是任何字串值,但必須不重複 代表使用者和用戶端,不得 容易猜測的字詞如果是存取權杖,也請記錄權杖的到期時間 通常在核發權杖後一小時。
- 在 HTTPS 內文中傳回下列 JSON 物件
回應:
{ "token_type": "熊", "access_token": "ACCESS_TOKEN", 「expires_in」:SECONDS_TO_EXPIRATION }
處理使用者資訊要求
userinfo 端點是 OAuth 2.0 受保護的資源,可傳回已連結使用者的聲明。除了下列用途外,不一定要實作並代管 userinfo 端點:
成功從權杖端點擷取存取權杖後,Google 會向您的使用者資訊端點傳送要求,以擷取已連結使用者的基本個人資料。
| userinfo 端點要求標頭 | |
|---|---|
Authorization header |
Bearer 類型的存取權杖。 |
舉例來說,如果您的 userinfo 端點位於
https://myservice.example.com/userinfo,要求可能如下所示:
GET /userinfo HTTP/1.1 Host: myservice.example.com Authorization: Bearer ACCESS_TOKEN
為了讓 userinfo 端點處理要求,請按照下列步驟操作:
- 從授權標頭擷取存取權杖,然後為與存取權杖相關聯的使用者傳回資訊。
- 如果存取權杖無效,請使用
WWW-Authenticate回應標頭傳回 HTTP 401 Unauthorized 錯誤。以下是 userinfo 錯誤回應的範例: 敬上 如果連結過程中傳回 401 未授權錯誤或其他失敗錯誤回應,將無法復原錯誤,擷取到的憑證將遭到捨棄,使用者必須再次啟動連結程序。HTTP/1.1 401 Unauthorized WWW-Authenticate: error="invalid_token", error_description="The Access Token expired"
如果存取權杖有效,則傳回並傳回 HTTP 200 回應,且 HTTPS 內文含有下列 JSON 物件 回應:
敬上 如果您的 userinfo 端點傳回 HTTP 200 成功回應,則會根據使用者的 Google 帳戶登錄擷取的權杖和憑證附加資訊。{ "sub": "USER_UUID", "email": "EMAIL_ADDRESS", "given_name": "FIRST_NAME", "family_name": "LAST_NAME", "name": "FULL_NAME", "picture": "PROFILE_PICTURE", }userinfo 端點回應 sub用來在系統中識別使用者的專屬 ID。 email使用者的電子郵件地址。 given_name選填:使用者的名字。 family_name選填:使用者的姓氏。 name選填:使用者全名。 picture選用:使用者的個人資料相片。
驗證實作
您可以使用 OAuth 2.0 Playground 工具驗證實作結果。
請在工具中按照下列步驟操作:
- 點選「Configuration」圖示 ,開啟 OAuth 2.0 設定視窗。
- 在「OAuth 流程」欄位中,選取「用戶端」。
- 在「OAuth 端點」欄位中,選取「自訂」。
- 在對應的欄位中指定 OAuth 2.0 端點,以及您指派給 Google 的用戶端 ID。
- 在「步驟 1」部分中,請勿選取任何 Google 範圍。請改為將這個欄位留空,或輸入有效的伺服器範圍 (如果您不使用 OAuth 範圍,則輸入任意字串)。完成後,按一下「授權 API」。
- 在「步驟 2」和「步驟 3」部分,請完成 OAuth 2.0 流程,並確認每個步驟都能正常運作。
您可以使用 Google 帳戶連結示範工具驗證實作成果。
在工具中執行下列步驟:
- 按一下「使用 Google 帳戶登入」按鈕。
- 選擇要連結的帳戶。
- 輸入服務 ID。
- 您可以選擇輸入一或多個要申請存取權的範圍。
- 按一下「開始試用」。
- 系統顯示提示時,請確認您可以同意或拒絕連結要求。
- 確認系統是否會將你重新導向至平台。