使用 OAuth 連結 Google 帳戶

帳戶連結會使用業界標準的 OAuth 2.0 隱含授權碼流程。您的服務必須支援符合 OAuth 2.0 標準的授權權杖交換端點。

隐式流程中,Google 会在用户的浏览器中打开您的授权端点。成功登录后,您将向 Google 返回一个长期访问令牌。现在,此访问令牌会包含在 Google 发送的每个请求中。

授权代码流程中,您需要两个端点:

  • 授权端点,用于向尚未登录的用户显示登录界面。授权端点还会创建一个短期授权代码,以记录用户对所请求访问权限的同意情况。

  • 令牌交换端点,负责两种类型的交换:

    1. 使用授权代码换取长期有效的刷新令牌和短期有效的访问令牌。当用户完成账号关联流程时,就会发生此交换。
    2. 将长期有效的刷新令牌换成短期有效的访问令牌。当 Google 需要新的访问令牌(因为现有访问令牌已过期)时,就会发生这种交换。

选择 OAuth 2.0 流程

虽然隐式流程更易于实现,但 Google 建议通过隐式流程签发的访问令牌永不过期。这是因为,在隐式流程中,令牌过期后,系统会强制用户重新关联其账号。如果您出于安全考虑需要令牌过期,我们强烈建议您改用授权码流程。

设计准则

本部分介绍了您为 OAuth 关联流程托管的用户屏幕的设计要求和建议。在 Google 应用调用该 API 后,您的平台会向用户显示登录 Google 页面和账号关联意见征求界面。同意关联账号后,系统会将用户重定向回 Google 的应用。

此图展示了用户将其 Google 账号与您的身份验证系统相关联的步骤。第一个屏幕截图显示了用户从您的平台发起的关联。第二张图片显示用户登录 Google,第三张图片显示用户同意并确认将其 Google 账号与您的应用相关联。最后一张屏幕截图显示 Google 应用中成功关联的用户账号。
图 1.账号关联用户登录 Google 和同意屏幕。

要求

  1. 您必须说明用户的账号将与 Google 相关联,而非 Google Home 或 Google 助理等特定 Google 产品相关联。

建议

建议您执行以下操作:

  1. 显示 Google 的隐私权政策。在同意屏幕上添加指向 Google 隐私权政策的链接。

  2. 要共享的数据。使用清晰简洁的语言告知用户 Google 需要哪些用户数据以及原因。

  3. 添加醒目的号召性用语。在用户同意页面上提供明确的号召性用语,例如“同意并关联”。这是因为用户需要了解他们需要与 Google 分享哪些数据才能关联账号。

  4. 可以取消。为用户提供返回或取消链接的途径,如果用户选择不进行关联。

  5. 明确的登录流程。确保用户有明确的 Google 账号登录方法,例如用户名和密码字段或使用 Google 账号登录

  6. 能够解除关联。提供一种可让用户解除关联的机制,例如指向您平台上账号设置的网址。或者,您也可以添加指向 Google 账号的链接,以便用户管理其关联的账号。

  7. 能够更改用户账号。建议用户切换账号的方法。如果用户通常拥有多个账号,这种做法尤为有益。

    • 如果用户必须关闭意见征求界面才能切换账号,请向 Google 发送可恢复的错误,以便用户可以使用 OAuth 关联隐式流程登录所需的账号。
  8. 添加您的徽标。在意见征求页面上显示您的公司徽标。 按照您的样式准则放置徽标。如果您还想显示 Google 的徽标,请参阅徽标和商标

建立專案

如要建立專案以使用帳戶連結,請按照下列步驟操作:

  1. 按一下 [Create Project]
  2. 輸入名稱或接受系統產生的建議。
  3. 確認或編輯其餘欄位。
  4. 點選「建立」

如要查看專案 ID,請按照下列步驟操作:

  1. 在到達網頁的表格中找出專案。專案 ID 會顯示在「ID」欄中。

Google 帳戶連結程序會顯示同意畫面,告知使用者要求存取資料的應用程式、要求存取的資料類型,以及適用條款。您必須先設定 OAuth 同意畫面,才能產生 Google API 用戶端 ID。

  1. 開啟 Google API 控制台的「OAuth 同意畫面」頁面。
  2. 如果出現提示,請選取您剛建立的專案。
  3. 在「OAuth 同意畫面」頁面中填寫表單,然後按一下「儲存」按鈕。

    應用程式名稱:要求同意的應用程式名稱。名稱應如實反映應用程式,且與使用者在其他地方看到的應用程式名稱一致。應用程式名稱會顯示在帳戶連結同意畫面上。

    應用程式標誌:同意畫面上的圖片,可協助使用者識別您的應用程式。標誌會顯示在帳戶連結同意畫面和帳戶設定頁面。

    支援電子郵件地址:方便使用者與您聯絡,洽詢同意聲明相關事宜。

    Google API 的範圍:範圍可讓應用程式存取使用者的私人 Google 資料。如果是 Google 帳戶連結用途,預設範圍 (電子郵件、個人資料、openid) 就已足夠,不需要新增任何敏感範圍。一般而言,最佳做法是在需要存取權時,逐步要求範圍,而非預先要求。瞭解詳情

    授權網域:為保障您與使用者的安全,Google 只允許應用程式透過 OAuth 驗證,使用授權網域。應用程式的連結必須託管於授權網域。瞭解詳情

    應用程式首頁連結:應用程式的首頁。必須託管在授權網域。

    應用程式隱私權政策連結:顯示在 Google 帳戶連結同意畫面上。必須託管在授權網域。

    應用程式服務條款連結 (選填):必須代管於授權網域。

    圖 1. 虛構應用程式 Tunery 的 Google 帳戶連結同意畫面

  4. 查看「驗證狀態」,如果應用程式需要驗證,請點按「送交驗證」按鈕,將應用程式送交驗證。詳情請參閱 OAuth 驗證規定

實作 OAuth 伺服器

授權碼流程的 OAuth 2.0 伺服器實作包含 服務透過 HTTPS 提供第一個端點 是授權端點,負責尋找或取得 徵得使用者同意並授予資料存取權授權端點會顯示 登入使用者介面,供尚未登入的使用者查看,且將同意 所要求的存取權第二個端點是權杖交換端點 用於取得加密字串 (稱為「權杖」),藉此授權使用者 存取您的服務。

當 Google 應用程式需要呼叫服務的其中一個 API 時,Google 會使用 這些端點都會一起取得權限,以便使用者呼叫這些 API 管理。

由 Google 發起的 OAuth 2.0 授權碼流程工作階段, 下列流程:

  1. Google 會在使用者的瀏覽器中開啟授權端點。如果流程 透過純語音裝置啟動動作,則 Google 將 到手機上
  2. 使用者登入後 (如果尚未登入),並將權限授予 Google 透過您的 API 存取他們的資料 (如果尚未授予權限)。
  3. 您的服務會建立授權碼,並傳回 Google。待辦 因此,請透過授權碼將使用者的瀏覽器重新導向回 Google 附加在要求中
  4. Google 將授權碼傳送至權杖交換端點 驗證程式碼的真實性,並傳回存取權杖更新權杖。存取權杖是服務 以憑證存取 API。更新權杖存在長期 憑證,可供 Google 儲存,用於取得新的存取權杖 過期。
  5. 使用者完成帳戶連結流程後, 來自 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

如要讓授權端點處理登入要求,請按照下列步驟操作: 步驟:

  1. 確認 client_id 與您指派給 Google 的用戶端 ID 相符,且 redirect_uri 與 Google 為您的服務提供的重新導向網址相符。這些檢查至關重要 存取非預期或設定錯誤的用戶端應用程式。如果跨平台支援 OAuth 2.0 流程,也可以確認 response_typecode
  2. 檢查使用者是否已登入您的服務。如果使用者未登入, 完成服務的登入或註冊流程。
  3. 產生授權代碼,讓 Google 用來存取您的 API。 授權碼可以是任何字串值,但必須不重複 代表使用者、該權杖所屬的用戶端,以及代碼的到期時間 而且您無法憑空猜測您通常會核發授權 驗證碼會在大約 10 分鐘後失效
  4. 請確認 redirect_uri 參數指定的網址包含 以下表單:
      https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID
      https://oauth-redirect-sandbox.googleusercontent.com/r/YOUR_PROJECT_ID
      
  5. 將使用者的瀏覽器重新導向至 redirect_uri 參數。附上 產生的原始值,以及您在重新導向時 方法是附加 codestate 參數。以下是 結果網址的範例:
    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_coderefresh_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_codecode 的值是您先前授予的授權碼 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 要求: 步驟:

  1. 驗證 client_id 會將要求來源識別為已授權的要求 ,且 client_secret 符合預期值。
  2. 請檢查授權碼是否有效且未過期,且 要求中指定的用戶端 ID 與 授權碼。
  3. 確認 redirect_uri 參數指定的網址相同 設為初始授權要求使用的值。
  4. 如果您無法驗證上述所有條件,請傳回 HTTP 400 「Bad Request」錯誤,內文為 {"error": "invalid_grant"}
  5. 否則,請使用授權碼中的使用者 ID 產生重新整理 權杖和存取權杖這些符記可以是任何字串值,但 必須明確代表憑證所屬的用戶端、 另一個使用者如果是存取權杖,也請記下 權杖,通常是在您核發權杖後 1 小時。 重新整理權杖沒有期限。
  6. 在 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 要求:

  1. 驗證 client_id 會將要求來源指定為 Google。 client_secret 與預期值相符
  2. 驗證更新權杖是否有效,以及 此請求會與更新權杖關聯的用戶端 ID 相符。
  3. 如果您無法驗證上述所有條件,請傳回 HTTP 400 「Bad Request」錯誤,以 {"error": "invalid_grant"} 為主體。
  4. 否則,請使用更新權杖的使用者 ID 產生存取權 產生下一個符記這些權杖可以是任何字串值,但必須不重複 代表使用者和用戶端,不得 容易猜測的字詞如果是存取權杖,也請記錄權杖的到期時間 通常在核發權杖後一小時。
  5. 在 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 端點處理要求,請按照下列步驟操作:

  1. 從授權標頭擷取存取權杖,然後為與存取權杖相關聯的使用者傳回資訊。
  2. 如果存取權杖無效,請使用 WWW-Authenticate 回應標頭傳回 HTTP 401 Unauthorized 錯誤。以下是 userinfo 錯誤回應的範例:
    HTTP/1.1 401 Unauthorized
    WWW-Authenticate: error="invalid_token",
    error_description="The Access Token expired"
    
    敬上 如果連結過程中傳回 401 未授權錯誤或其他失敗錯誤回應,將無法復原錯誤,擷取到的憑證將遭到捨棄,使用者必須再次啟動連結程序。
  3. 如果存取權杖有效,則傳回並傳回 HTTP 200 回應,且 HTTPS 內文含有下列 JSON 物件 回應:

    {
    "sub": "USER_UUID",
    "email": "EMAIL_ADDRESS",
    "given_name": "FIRST_NAME",
    "family_name": "LAST_NAME",
    "name": "FULL_NAME",
    "picture": "PROFILE_PICTURE",
    }
    敬上 如果您的 userinfo 端點傳回 HTTP 200 成功回應,則會根據使用者的 Google 帳戶登錄擷取的權杖和憑證附加資訊。

    userinfo 端點回應
    sub 用來在系統中識別使用者的專屬 ID。
    email 使用者的電子郵件地址。
    given_name 選填:使用者的名字。
    family_name 選填:使用者的姓氏。
    name 選填:使用者全名。
    picture 選用:使用者的個人資料相片。

驗證實作

您可以使用 OAuth 2.0 Playground 工具驗證實作結果。

請在工具中按照下列步驟操作:

  1. 點選「Configuration」圖示 ,開啟 OAuth 2.0 設定視窗。
  2. 在「OAuth 流程」欄位中,選取「用戶端」
  3. 在「OAuth 端點」欄位中,選取「自訂」
  4. 在對應的欄位中指定 OAuth 2.0 端點,以及您指派給 Google 的用戶端 ID。
  5. 在「步驟 1」部分中,請勿選取任何 Google 範圍。請改為將這個欄位留空,或輸入有效的伺服器範圍 (如果您不使用 OAuth 範圍,則輸入任意字串)。完成後,按一下「授權 API」
  6. 在「步驟 2」和「步驟 3」部分,請完成 OAuth 2.0 流程,並確認每個步驟都能正常運作。

您可以使用 Google 帳戶連結示範工具驗證實作成果。

在工具中執行下列步驟:

  1. 按一下「使用 Google 帳戶登入」按鈕。
  2. 選擇要連結的帳戶。
  3. 輸入服務 ID。
  4. 您可以選擇輸入一或多個要申請存取權的範圍。
  5. 按一下「開始試用」
  6. 系統顯示提示時,請確認您可以同意或拒絕連結要求。
  7. 確認系統是否會將你重新導向至平台。