總覽
OAuth 式 Google 登入簡化連結會在 OAuth 連結之外新增 Google 登入。這不僅能為 Google 使用者提供流暢的連結體驗,還能啟用帳戶,讓使用者透過自己的 Google 帳戶建立新帳戶。
如要透過 OAuth 和 Google 登入功能連結帳戶,請按照下列一般步驟操作:
- 首先,請要求使用者同意存取自己的 Google 個人資料。
- 使用設定檔中的資訊,確認使用者帳戶是否存在。
- 如果是現有使用者,請連結帳戶。
- 如果您在驗證系統中找不到相符的 Google 使用者,請驗證 Google 收到的 ID 權杖。接著,您可以根據 ID 權杖中包含的設定檔資訊建立使用者。

圖 1. 使用者可透過簡化連結的方式在手機上連結自己的帳戶
簡化連結的相關規定
- 實作基本網站 OAuth 連結流程。您的服務必須支援符合 OAuth 2.0 規定的授權和憑證交換端點。
- 您的權杖交換端點必須支援 JSON Web Token (JWT) 宣告,並導入
check
、create
和get
意圖。
實作 OAuth 伺服器
您的權杖交換端點必須支援 check
、create
、get
意圖。下圖顯示透過帳戶連結流程完成的步驟,並指出呼叫不同意圖的時機:
- 使用者在驗證系統中是否有帳戶?(使用者選取「是」或「否」即可決定)
- 是:使用者是否透過與 Google 帳戶相關聯的電子郵件地址登入平台?(使用者選取「是」或「否」即可決定)
- 是:使用者在驗證系統中是否有相符的帳戶?(系統會呼叫
check intent
進行確認)- 是:系統會呼叫
get intent
,如果成功擷取意圖,系統就會連結帳戶。 - 否:建立新帳戶?(使用者選取「是」或「否」即可決定)
- 是:系統會呼叫
create intent
,並在建立意圖傳回成功時連結帳戶。 - 否:系統會觸發網路 OAuth 流程、將使用者導向瀏覽器,且使用者可選擇連結其他電子郵件地址。
- 是:系統會呼叫
- 是:系統會呼叫
- 否:系統會觸發網路 OAuth 流程,系統會將使用者導向使用者瀏覽器,並讓使用者選擇連結其他電子郵件。
- 是:使用者在驗證系統中是否有相符的帳戶?(系統會呼叫
- 否:使用者在驗證系統中是否有相符的帳戶?(系統會呼叫
check intent
進行確認)- 是:系統會呼叫
get intent
,如果成功擷取意圖,系統就會連結帳戶。 - 否:系統會呼叫
create intent
,並在建立意圖傳回成功時連結帳戶。
- 是:系統會呼叫
- 是:使用者是否透過與 Google 帳戶相關聯的電子郵件地址登入平台?(使用者選取「是」或「否」即可決定)
檢查現有的使用者帳戶 (檢查意圖)
使用者表示同意存取其 Google 個人資料後,Google 會傳送一項要求,其中包含對 Google 使用者身分進行簽署的聲明。清單包含使用者 Google 帳戶 ID、名稱和電子郵件地址等資訊。您為專案設定的權杖交換端點會處理該項要求。
如果驗證系統中已有對應的 Google 帳戶,您的權杖交換端點會以 account_found=true
回應。如果 Google 帳戶與現有使用者不相符,您的權杖交換端點會傳回 account_found=false
傳回 HTTP 404 Not Found 錯誤。
這項要求的格式如下:
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 Token (JWT) 提供已簽署的 Google 使用者身分宣告。JWT 內含使用者 Google 帳戶 ID、名稱和電子郵件地址等資訊。 |
client_id |
您指派給 Google 的用戶端 ID。 |
client_secret |
您指派給 Google 的用戶端密鑰。 |
如要回應 check
意圖要求,您的權杖交換端點必須執行下列步驟:
- 驗證並解碼 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在創建Google帳戶時最初驗證了用戶時, email_verfied
也可能為true,但是此後第三方電子郵件帳戶的所有權可能已更改。
檢查驗證系統中是否已有這個 Google 帳戶
請確認下列任一種情況是否成立:
- 這個 Google 帳戶 ID (位於宣告的
sub
欄位中) 位於使用者資料庫中。 - 宣告中的電子郵件地址與您的使用者資料庫中的使用者相符。
只要符合其中一個條件,就表示使用者已註冊。在這種情況下,系統會傳回類似以下的回應:
HTTP/1.1 200 Success Content-Type: application/json;charset=UTF-8 { "account_found":"true", }
如果設定中指定的 Google 帳戶 ID 和電子郵件地址均不符合資料庫中的使用者,表示使用者尚未註冊。在這個情況下,您的權杖交換端點需要傳回指定 "account_found": "false"
的 HTTP 404 錯誤,如以下範例所示:
HTTP/1.1 404 Not found Content-Type: application/json;charset=UTF-8 { "account_found":"false", }
處理自動連結 (取得意圖)
使用者表示同意存取其 Google 個人資料後,Google 會傳送一項要求,其中包含對 Google 使用者身分進行簽署的聲明。清單包含使用者 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 |
JSON Web Token (JWT) 提供已簽署的 Google 使用者身分宣告。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在創建Google帳戶時最初驗證了用戶時, email_verfied
也可能為true,但是此後第三方電子郵件帳戶的所有權可能已更改。
檢查驗證系統中是否已有這個 Google 帳戶
請確認下列任一種情況是否成立:
- 這個 Google 帳戶 ID (位於宣告的
sub
欄位中) 位於使用者資料庫中。 - 宣告中的電子郵件地址與您的使用者資料庫中的使用者相符。
如果找到使用者的帳戶,請發出存取憑證,並在 HTTPS 回應的內文中傳回 JSON 物件的值,如以下範例所示:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
在某些情況下,根據 ID 符記連結帳戶的使用者可能無法使用。如果發生任何原因,您的符記交換端點必須傳回以 error=linking_error
表示的 HTTP 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 錯誤回應時,Google 會以 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 |
JSON Web Token (JWT) 提供已簽署的 Google 使用者身分宣告。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在創建Google帳戶時最初驗證了用戶時, email_verfied
也可能為true,但是此後第三方電子郵件帳戶的所有權可能已更改。
驗證使用者資訊及建立新帳戶
請確認下列任一種情況是否成立:
- 這個 Google 帳戶 ID (位於宣告的
sub
欄位中) 位於使用者資料庫中。 - 宣告中的電子郵件地址與您的使用者資料庫中的使用者相符。
如果符合其中一個條件,提示使用者將現有的帳戶與 Google 帳戶連結。如要這麼做,請以指定 error=linking_error
的 HTTP 401 錯誤回應要求,並將使用者的電子郵件地址設為 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 錯誤回應時,Google 會以 login_hint
做為參數,將使用者傳送至您的授權端點。使用者在瀏覽器中會使用 OAuth 連結流程完成帳戶連結程序。
如果兩個條件都不符合,請使用 JWT 提供的資訊來建立新的使用者帳戶。一般來說,新帳戶通常未設定密碼。建議您將 Google 登入新增到其他平台,讓使用者能夠在應用程式的介面上透過 Google 登入。或者,您也可以透過電子郵件向使用者傳送可啟動密碼救援流程的連結,讓使用者能夠設定在其他平台上登入的密碼。
建立程序完成後,請發出存取憑證 ,並在 HTTPS 回應的主體中傳回 JSON 物件中的值,如以下範例所示:
{ "token_type": "Bearer", "access_token": "ACCESS_TOKEN", "expires_in": SECONDS_TO_EXPIRATION }
取得 Google API 用戶端 ID
在帳戶連結註冊程序過程中,您必須提供 Google API 用戶端 ID。
如要取得在完成 OAuth 連結步驟中建立的專案,取得 API 用戶端 ID。如要這樣做,請完成下列步驟:
- 開啟 Google API 控制台的「憑證」頁面。
建立或選取 Google API 專案。
如果專案沒有網頁應用程式類型的用戶端 ID,請按一下 [建立憑證 > OAuth 用戶端 ID] 來建立。請務必在「Authorized JavaScript origins」(已授權的 JavaScript 來源) 方塊中加入您的網站網域。執行本機測試或開發作業時,必須將「
http://localhost
」和「http://localhost:<port_number>
」新增至「Authorized JavaScript origins」(已獲授權的 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.