Google 的 OAuth 2.0 API 可用於驗證和授權。本文說明我們用於驗證的 OAuth 2.0 實作,符合 OpenID Connect 規格,並通過 OpenID 認證。「使用 OAuth 2.0 存取 Google API」中的說明文件也適用於這項服務。如要以互動方式探索這項通訊協定,建議您使用 Google OAuth 2.0 Playground。如要在 Stack Overflow 尋求協助,請在問題中加上「google-oauth」標記。
設定 OAuth 2.0
應用程式必須先在 Google Cloud 控制台中設定專案,才能使用 Google 的 OAuth 2.0 驗證系統讓使用者登入。設定專案後,您就能取得 OAuth 2.0 憑證、設定重新導向 URI,以及自訂使用者在同意畫面中看到的品牌資訊 (選用)。您也可以使用 Cloud 控制台建立服務帳戶、啟用計費功能、設定篩選條件及執行其他工作。詳情請參閱 Google Cloud 控制台說明。
取得 OAuth 2.0 憑證
您需要 OAuth 2.0 憑證 (包括用戶端 ID 和用戶端密鑰),才能驗證使用者並存取 Google API。
如要查看特定 OAuth 2.0 憑證的用戶端 ID 和用戶端密鑰,請按一下以下文字:「Select credential」(選取憑證)。在開啟的視窗中,選擇專案和所需憑證,然後按一下「View」(查看)。
或者,您也可以在 Cloud 控制台的「Clients」(用戶端) 頁面中查看用戶端 ID 和用戶端密鑰:
- 前往「客戶」頁面。
- 按一下客戶名稱或「編輯」圖示 create。用戶端 ID 和密鑰會顯示在頁面頂端。
設定重新導向 URI
您在 Cloud 控制台中設定的重新導向 URI,會決定 Google 將驗證要求的回應傳送至何處。
如要建立、查看或編輯特定 OAuth 2.0 憑證的重新導向 URI,請按照下列步驟操作:
- 前往「客戶」頁面。
- 按一下客戶。
- 查看或編輯重新導向 URI。
如果「Clients」(用戶端) 頁面中未列出任何用戶端,表示專案沒有 OAuth 憑證。如要建立,請按一下「建立用戶端」。
自訂使用者同意畫面
對使用者來說,OAuth 2.0 驗證體驗包含同意畫面,其中會說明使用者提供的資訊和適用條款。舉例來說,使用者登入時,系統可能會要求他們授予應用程式存取權,允許應用程式存取他們的電子郵件地址和基本帳戶資訊。您可以使用 scope 參數要求存取這項資訊,該參數會包含在應用程式的驗證要求中。您也可以使用範圍要求存取其他 Google API。
使用者同意畫面也會顯示品牌資訊,例如產品名稱、標誌和首頁網址。您可以在 Cloud 控制台中控管品牌資訊。
如要啟用專案的同意畫面,請按照下列步驟操作:
- 在 Google Cloud 控制台中開啟「Branding」(品牌宣傳) 頁面。
- 按照系統說明選取專案,或建立新專案。
- 填寫表單,然後按一下「Save」。
下列同意聲明對話方塊顯示,當要求中同時存在 OAuth 2.0 和 Google 雲端硬碟範圍時,使用者會看到的內容。(這個一般對話方塊是使用 Google OAuth 2.0 Playground 產生,因此不含在 Cloud 控制台中設定的品牌資訊)。

存取服務
Google 和第三方提供的程式庫,可協助您處理驗證使用者和取得 Google API 存取權的許多實作細節。例如 Google Identity 服務 和 Google 用戶端程式庫,適用於多種平台。
如果您選擇不使用程式庫,請按照本文件其餘部分的指示操作,其中說明瞭可用程式庫底層的 HTTP 要求流程。
驗證使用者
驗證使用者身分時,需要取得並驗證 ID 權杖。ID 權杖是 OpenID Connect 的標準化功能,用於在網際網路上共用身分聲明。
最常用來驗證使用者身分並取得 ID 權杖的方法,稱為「伺服器」流程和「隱含」流程。伺服器流程可讓應用程式的後端伺服器,驗證使用瀏覽器或行動裝置的使用者身分。當用戶端應用程式 (通常是在瀏覽器中執行的 JavaScript 應用程式) 需要直接存取 API,而非使用後端伺服器時,就會使用隱含流程。
本文說明如何執行伺服器流程來驗證使用者。隱含流程在用戶端處理及使用權杖時,會產生安全性風險,因此複雜度明顯較高。如需實作隱含流程,強烈建議使用 Google Identity 服務。
伺服器流程
請務必在 Cloud 控制台中設定應用程式,以便使用這些通訊協定並驗證使用者。當使用者嘗試使用 Google 帳戶登入時,您需要:
1. 建立防偽狀態權杖
您必須防範偽造要求攻擊,保護使用者安全。第一步是建立專屬工作階段符記,用於保存應用程式和使用者用戶端之間的狀態。之後,您會將這個不重複的工作階段符記與 Google OAuth 登入服務傳回的驗證回應進行比對,確認是使用者提出要求,而非惡意攻擊者。這類權杖通常稱為跨網站要求偽造 (CSRF) 權杖。
狀態權杖的理想選擇是使用高品質隨機數字產生器,建構約 30 個字元的字串。另一個是雜湊,產生方式是使用後端保密的金鑰,簽署部分工作階段狀態變數。
下列程式碼示範如何產生不重複的工作階段符記。
PHP
您必須下載適用於 PHP 的 Google API 用戶端程式庫,才能使用這個範例。
// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = bin2hex(random_bytes(128/8));
$app['session']->set('state', $state);
// Set the client ID, token state, and application name in the HTML while
// serving it.
return $app['twig']->render('index.html', array(
'CLIENT_ID' => CLIENT_ID,
'STATE' => $state,
'APPLICATION_NAME' => APPLICATION_NAME
));
Java
您必須下載適用於 Java 的 Google API 用戶端程式庫,才能使用這個範例。
// Create a state token to prevent request forgery.
// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
request.session().attribute("state", state);
// Read index.html into memory, and set the client ID,
// token state, and application name in the HTML before serving it.
return new Scanner(new File("index.html"), "UTF-8")
.useDelimiter("\\A").next()
.replaceAll("[{]{2}\\s*CLIENT_ID\\s*[}]{2}", CLIENT_ID)
.replaceAll("[{]{2}\\s*STATE\\s*[}]{2}", state)
.replaceAll("[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}",
APPLICATION_NAME);
Python
您必須下載 Python 適用的 Google API 用戶端程式庫,才能使用這個範例。
# Create a state token to prevent request forgery.
# Store it in the session for later validation.
state = hashlib.sha256(os.urandom(1024)).hexdigest()
session['state'] = state
# Set the client ID, token state, and application name in the HTML while
# serving it.
response = make_response(
render_template('index.html',
CLIENT_ID=CLIENT_ID,
STATE=state,
APPLICATION_NAME=APPLICATION_NAME))
2. 傳送驗證要求給 Google
下一步是使用適當的 URI 參數,建立 HTTPS GET 要求。請注意,在這個程序的所有步驟中,請使用 HTTPS 而非 HTTP;HTTP 連線會遭到拒絕。您應使用 authorization_endpoint 中繼資料值,從導覽文件擷取基準 URI。以下討論假設基礎 URI 為 https://accounts.google.com/o/oauth2/v2/auth。
如要提出基本要求,請指定下列參數:
client_id,可從 Cloud 控制台的「Clients」(用戶端) 頁面取得。response_type:在基本授權碼流程要求中,應為code。(詳情請參閱response_type)。scope:在基本要求中應為openid email。(詳情請參閱scope)。redirect_uri應為伺服器上接收 Google 回應的 HTTP 端點。這個值必須與您在 Cloud 控制台「Credentials」(憑證) 頁面中,為 OAuth 2.0 用戶端設定的其中一個已授權重新導向 URI 完全相符。如果這個值與授權 URI 不符,要求就會失敗,並顯示redirect_uri_mismatch錯誤。state應包含防偽造專屬工作階段符記的值,以及使用者返回應用程式時復原背景資訊所需的任何其他資訊,例如起始網址。(詳情請參閱state)。nonce是應用程式產生的隨機值,可啟用重播防護功能 (如有)。login_hint可以是使用者的電子郵件地址或sub字串,相當於使用者的 Google ID。如果您未提供login_hint,且使用者已登入,同意畫面會要求使用者核准將電子郵件地址提供給您的應用程式。(詳情請參閱login_hint)。- 使用
hd參數,為與 Google Workspace 或 Cloud 組織相關聯的特定網域使用者,最佳化 OpenID Connect 流程 (詳情請參閱hd)。
以下是完整的 OpenID Connect 驗證 URI 範例,其中包含換行和空格,方便閱讀:
https://accounts.google.com/o/oauth2/v2/auth? response_type=code& client_id=424911365001.apps.googleusercontent.com& scope=openid%20email& redirect_uri=https%3A//developers.google.com/oauthplayground& state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2-login-demo.example.com%2FmyHome& login_hint=jsmith@example.com& nonce=0394852-3190485-2490358& hd=example.com
如果應用程式要求任何新的使用者資訊,或要求先前未經核准的帳戶存取權,則必須徵得使用者同意。
3. 確認防偽狀態權杖
系統會將回應傳送至您在要求中指定的 redirect_uri。所有回應都會在查詢字串中傳回:
https://developers.google.com/oauthplayground?state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foa2cb.example.com%2FmyHome&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&scope=openid%20email%20https://www.googleapis.com/auth/userinfo.email
根據 RFC 6749,用戶端必須忽略無法辨識的回應參數。在伺服器上,您必須確認從 Google 收到的 state 與您在步驟 1 中建立的工作階段符記相符。這項來回驗證有助於確認要求是由使用者發出,而非惡意指令碼。
以下程式碼示範如何確認您在步驟 1 建立的工作階段符記:
PHP
您必須下載適用於 PHP 的 Google API 用戶端程式庫,才能使用這個範例。
// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
return new Response('Invalid state parameter', 401);
}
Java
您必須下載適用於 Java 的 Google API 用戶端程式庫,才能使用這個範例。
// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if (!request.queryParams("state").equals(
request.session().attribute("state"))) {
response.status(401);
return GSON.toJson("Invalid state parameter.");
}
Python
您必須下載適用於 Python 的 Google API 用戶端程式庫,才能使用這個範例。
# Ensure that the request is not a forgery and that the user sending
# this connect request is the expected user.
if request.args.get('state', '') != session['state']:
response = make_response(json.dumps('Invalid state parameter.'), 401)
response.headers['Content-Type'] = 'application/json'
return response
4. 將code換成存取權杖和 ID 權杖
回應包含 code 參數,這是一次性授權碼,伺服器可用來交換存取權杖和 ID 權杖。伺服器會傳送 HTTPS POST 要求來進行這項交換。POST 要求會傳送至權杖端點,您應使用 token_endpoint 中繼資料值,從導覽文件擷取該端點。以下討論假設端點為 https://oauth2.googleapis.com/token。要求必須在 POST 主體中包含下列參數:
| 欄位 | |
|---|---|
code |
從初始要求傳回的授權碼。 |
client_id |
您從 Cloud 控制台「Clients」(用戶端) 頁面取得的用戶端 ID,詳情請參閱「取得 OAuth 2.0 憑證」。 |
client_secret |
您從 Cloud 控制台「Clients」(用戶端) 頁面取得的用戶端密鑰,如「取得 OAuth 2.0 憑證」一節所述。 |
redirect_uri |
在 Cloud 控制台「Clients」(用戶端) 頁面中,為指定 client_id 授權的重新導向 URI,如「設定重新導向 URI」一節所述。 |
grant_type |
這個欄位必須包含 authorization_code 值,
如 OAuth 2.0 規格所定義。 |
實際要求可能如下所示:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your-client-id& client_secret=your-client-secret& redirect_uri=https%3A//developers.google.com/oauthplayground& grant_type=authorization_code
如果這項要求成功,回應會包含 JSON 陣列中的下列欄位:
| 欄位 | |
|---|---|
access_token |
可傳送至 Google API 的權杖。 |
expires_in |
存取權杖的剩餘生命週期 (以秒為單位)。 |
id_token |
JWT:包含 Google 數位簽署的使用者身分資訊。 |
scope |
access_token 授予的存取權範圍,以空格分隔、區分大小寫的字串清單表示。 |
token_type |
識別傳回的權杖類型。目前,這個欄位的值一律為 Bearer。 |
refresh_token |
(選填)
只有在驗證要求中將 |
5. 從 ID 權杖取得使用者資訊
ID 權杖是 JWT (JSON Web Token),也就是經過加密簽署、Base64 編碼的 JSON 物件。一般來說,您必須先驗證 ID 權杖,才能使用該權杖。不過,由於您是透過不含中介者的 HTTPS 通道直接與 Google 通訊,並使用用戶端密鑰向 Google 驗證身分,因此可以確信收到的權杖確實來自 Google 且有效。如果伺服器將 ID 權杖傳遞至應用程式的其他元件,則其他元件在使用權杖之前,務必驗證權杖。
由於大多數 API 程式庫會將驗證作業與解碼 base64url 編碼值和剖析 JSON 的作業結合,因此您在存取 ID 權杖中的聲明時,可能還是會驗證權杖。
ID 權杖的酬載
ID 權杖是 JSON 物件,包含一組名稱/值組合。以下是範例,格式經過調整,方便閱讀:
{
"iss": "https://accounts.google.com",
"azp": "1234987819200.apps.googleusercontent.com",
"aud": "1234987819200.apps.googleusercontent.com",
"sub": "10769150350006150715113082367",
"at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
"hd": "example.com",
"email": "jsmith@example.com",
"email_verified": "true",
"iat": 1353601026,
"exp": 1353604926,
"nonce": "0394852-3190485-2490358"
}
Google ID 權杖可能包含下列欄位 (稱為「宣告」):
| 領取 | 自行提供 | 說明 |
|---|---|---|
aud |
一律 | 這個 ID 權杖的目標對象。必須是應用程式的其中一個 OAuth 2.0 用戶端 ID。 |
exp |
一律 | ID 權杖的到期時間,超過這個時間後,系統就不會接受該權杖。以 Unix 紀元時間表示 (整數秒)。 |
iat |
一律 | ID 權杖的核發時間。以 Unix 紀元時間表示 (整數秒)。 |
iss |
一律 | 回應核發者的核發者 ID。Google ID 權杖一律為 https://accounts.google.com 或 accounts.google.com。 |
sub |
一律 | 使用者的 ID,在所有 Google 帳戶中不重複,且不會重複使用。Google 帳戶在不同時間點可以有多個電子郵件地址,但 sub 值一律不會變更。在應用程式中使用 sub 做為使用者的專屬 ID 鍵。長度上限為 255 個 ASCII 字元 (區分大小寫)。 |
amr |
JSON 字串陣列,用於識別登入 Google 帳戶時使用的驗證方式。如果存在,則包含下列一或多個可能的 [IANA.AMR] 值:
amr 宣告,且在設定中啟用時,才會顯示。
|
|
auth_time |
使用者驗證的時間,以 JSON 數字表示自 Unix 紀元 (1970 年 1 月 1 日 00:00:00 UTC) 起經過的秒數。如果驗證要求包含 auth_time 宣告,且設定中已啟用該宣告,系統就會提供這項資訊。 |
|
at_hash |
存取權杖雜湊。驗證存取權杖是否與身分權杖繫結。如果 ID 權杖是在伺服器流程中以 access_token 值核發,則一律會包含這項聲明。這項聲明可做為防範跨網站偽造要求攻擊的替代機制,但如果您按照步驟 1 和步驟 3 操作,就不需要驗證存取權杖。 |
|
azp |
授權簡報者的client_id。只有在要求 ID 權杖的一方與 ID 權杖的目標對象不同時,才需要這項聲明。在 Google,混合式應用程式可能就是這種情況,其中網頁應用程式和 Android 應用程式具有不同的 OAuth 2.0 client_id,但共用同一個 Google API 專案。 |
|
email |
使用者的電子郵件地址。只有在要求中加入 email 範圍時,系統才會提供這項資訊。這個聲明的值可能不是這個帳戶專屬,且可能會隨時間變更,因此請勿將這個值做為連結至使用者記錄的主要 ID。您也無法依賴 email 宣告的網域來識別 Google Workspace 或 Cloud 機構的使用者,請改用 hd 宣告。
|
|
email_verified |
如果使用者的電子郵件地址已通過驗證,則為 True,否則為 False。 | |
family_name |
使用者的姓氏。如果存在 name 聲明,則可能會提供。 |
|
given_name |
使用者的名字。如果存在 name 聲明,則可能會提供。 |
|
hd |
與使用者 Google Workspace 或 Cloud 組織相關聯的網域。 只有在使用者屬於 Google Cloud 機構時,才會提供這項資訊。如要限制只有特定網域的成員才能存取資源,請務必勾選這項聲明。如果沒有這個宣告,表示帳戶不屬於 Google 代管網域。 | |
locale |
使用者的語言代碼,以 BCP 47 語言標記表示。如果存在 name 聲明,則可能會提供。 |
|
name |
使用者的全名,以可顯示的形式呈現。可能在下列情況提供:
如果存在 |
|
nonce |
應用程式在驗證要求中提供的 nonce 值。
請務必只顯示這個值一次,防範重送攻擊。 |
|
picture |
使用者個人資料相片的網址。可能在下列情況提供:
如果存在 |
|
profile |
使用者個人資料頁面的網址。可能在下列情況提供:
如果存在 |
6. 驗證使用者
從 ID 權杖取得使用者資訊後,請查詢應用程式的使用者資料庫。如果使用者已存在於資料庫中,且 Google API 回應符合所有登入要求,您應為該使用者啟動應用程式工作階段。
如果使用者不在使用者資料庫中,請將使用者重新導向至新使用者註冊流程。您可以根據從 Google 收到的資訊自動註冊使用者,或至少預先填入註冊表單中所需的許多欄位。除了 ID 權杖中的資訊外,您也可以在使用者個人資料端點取得其他使用者個人資料資訊。
進階主題
下列各節將進一步說明 Google OAuth 2.0 API。本文資訊適用於對驗證和授權有進階需求的開發人員。
存取其他 Google API
使用 OAuth 2.0 進行驗證的其中一項優點,是應用程式可以在驗證使用者的同時,取得代表使用者使用其他 Google API (例如 YouTube、Google 雲端硬碟、日曆或聯絡人) 的權限。如要這麼做,請在傳送給 Google 的驗證要求中加入所需的其他範圍。舉例來說,如要在驗證要求中加入使用者的年齡層,請傳遞 openid email https://www.googleapis.com/auth/profile.agerange.read 的範圍參數。系統會在同意畫面上適當提示使用者。您從 Google 收到的存取權杖,可讓應用程式存取與您要求並獲准的存取範圍相關的所有 API。
更新權杖
在 API 存取權要求中,您可以要求在 code 交換期間傳回更新權杖。更新權杖可讓應用程式在使用者未登入時,持續存取 Google API。如要要求更新權杖,請在驗證要求中,將 access_type 參數設為 offline。
注意事項:
- 請務必安全且永久地儲存更新權杖,因為您只能在首次執行程式碼交換流程時取得更新權杖。
- 核發的更新權杖數量有限制:每個用戶端/使用者組合有一個限制,而所有用戶端中的每個使用者也有一個限制。如果應用程式要求過多更新權杖,可能會達到這些限制,導致舊的更新權杖停止運作。
詳情請參閱「重新整理存取權杖 (離線存取)」。
提示使用者重新同意
您可以在驗證要求中,將 prompt 參數設為 consent,提示使用者重新授權應用程式。如果包含 prompt=consent,則每次應用程式要求授權存取範圍時,都會顯示同意畫面,即使先前已將所有範圍授予 Google API 專案也一樣。因此,請只在必要時加入 prompt=consent。
如要進一步瞭解 prompt 參數,請參閱「驗證 URI 參數」表格中的 prompt。
驗證 URI 參數
下表更完整地說明 Google 的 OAuth 2.0 驗證 API 接受的參數。
| 參數 | 必填 | 說明 | ||||||
|---|---|---|---|---|---|---|---|---|
client_id |
(必填) | 您從 Cloud 控制台「Clients」(用戶端) 頁面取得的用戶端 ID 字串,如「取得 OAuth 2.0 憑證」一節所述。 | ||||||
nonce |
(必填) | 應用程式產生的隨機值,可啟用重送防護機制。 | ||||||
response_type |
(必填) | 如果值為 code,則會啟動基本授權碼流程,需要向權杖端點傳送 POST 才能取得權杖。如果值為 token id_token 或 id_token token,系統會啟動隱含流程,要求在重新導向 URI 使用 JavaScript,從 URI #fragment 識別碼擷取權杖。 |
||||||
redirect_uri |
(必填) | 決定回應的傳送位置。這個參數的值必須與您在 Cloud 控制台「Clients」(用戶端) 頁面中設定的其中一個授權重新導向值完全相符 (包括 HTTP 或 HTTPS 配置、大小寫和結尾的「/」(如有))。 | ||||||
scope |
(必填) | 範圍參數必須以 如果存在 如果存在 除了這些 OpenID 專屬範圍外,範圍引數也可以包含其他範圍值。所有範圍值都必須以空格分隔。舉例來說,如果您想取得使用者 Google 雲端硬碟中個別檔案的存取權,範圍參數可能會是 如要瞭解可用的範圍,請參閱「Google API 適用的 OAuth 2.0 範圍」,或您要使用的 Google API 說明文件。 |
||||||
state |
(選用,但強烈建議) | 在通訊協定中來回傳送的不透明字串,也就是說,在基本流程中,它會以 URI 參數的形式傳回,而在隱含流程中,則會以 URI
|
||||||
access_type |
(選填) | 允許的值為 offline 和 online。離線存取一節說明瞭這項設定的效果;如果要求的是存取權杖,除非指定 offline 值,否則用戶端不會收到更新權杖。 |
||||||
claims |
(選填) |
claims 參數用於指定一或多個選用欄位,以便納入 userinfo 端點或驗證要求 ID 權杖回應類型。這個值是 JSON 物件,包含回應類型和要求的宣告。Google 伺服器接受下列聲明要求:
|
||||||
display |
(選填) | ASCII 字串值,用於指定授權伺服器如何顯示驗證和同意聲明使用者介面頁面。Google 伺服器會接受下列指定值,但這些值不會影響通訊協定流程行為:page、popup、touch 和 wap。 |
||||||
hd |
(選填) | 簡化 Google Cloud 組織擁有的帳戶登入程序。加入 Google Cloud 機構網域 (例如 mycollege.edu),即可指定帳戶選取 UI 應針對該網域的帳戶進行最佳化。如要針對 Google Cloud 機構帳戶進行一般最佳化,而非僅針對單一 Google Cloud 機構網域,請將值設為星號 ( 請勿依賴這項 UI 最佳化功能來控管可存取應用程式的使用者,因為用戶端要求可以修改。請務必驗證傳回的 ID 權杖是否包含符合預期的 |
||||||
include_granted_scopes |
(選填) | 如果這個參數的值為 true,且授權要求獲得核准,則授權將包含先前授予這個使用者/應用程式組合的其他範圍授權;請參閱「
漸進式授權」。請注意,您無法透過安裝版應用程式流程執行漸進式授權。 |
||||||
login_hint |
(選填) | 如果應用程式知道要驗證的使用者,可以將這個參數做為提示提供給驗證伺服器。傳遞這項提示會隱藏帳戶選擇器,並預填登入表單上的電子郵件方塊,或選取適當的工作階段 (如果使用者使用多帳戶登入),這有助於避免應用程式登入錯誤使用者帳戶時發生的問題。這個值可以是電子郵件地址或 sub 字串,相當於使用者的 Google ID。 |
||||||
prompt |
(選填) | 以空格分隔的字串值清單,指定授權伺服器是否提示使用者重新驗證及同意。可能的值如下:
如未指定任何值,且使用者先前未授權存取,系統會向使用者顯示同意畫面。 |
||||||
hl |
(選填) | BCP 47 語言標記,用於指定登入、帳戶選擇工具和同意畫面顯示的語言。如未提供這項參數,系統會預設使用使用者的 Google 帳戶或瀏覽器設定。舉例來說,如要要求英式英文的使用者介面,請將參數設為 en-GB。 |
||||||
驗證 ID 權杖
除非您知道 ID 權杖直接來自 Google,否則必須在伺服器上驗證所有 ID 權杖。舉例來說,伺服器必須驗證從用戶端應用程式收到的任何 ID 權杖是否真實。
以下是您可能需要將 ID 權杖傳送至伺服器的常見情況:
- 傳送 ID 權杖和需要驗證的要求。ID 權杖會指出提出要求的特定使用者,以及該 ID 權杖授予的用戶端。
ID 權杖屬於機密資訊,如果遭到攔截,可能會遭到濫用。您必須確保這些權杖是以安全的方式處理,方法是只透過 HTTPS 傳輸,且只使用 POST 資料或在要求標頭中傳輸。如果您將 ID 權杖儲存在伺服器上,也必須安全地儲存。
ID 權杖的其中一項優點是,您可以在應用程式的不同元件之間傳遞這些權杖。這些元件可以使用 ID 權杖做為輕量級驗證機制,驗證應用程式和使用者。不過,您必須先驗證 ID 權杖,才能使用其中的資訊,或將其視為使用者已通過驗證的聲明。
驗證 ID 權杖需要執行幾個步驟:
- 確認 ID 權杖已由核發者正確簽署。Google 核發的權杖會使用導覽文件
jwks_uri中繼資料值中指定 URI 的其中一個憑證簽署。 - 確認 ID 權杖中
iss宣告的值等於https://accounts.google.com或accounts.google.com。 - 確認 ID 權杖中
aud宣告的值等於應用程式的用戶端 ID。 - 確認 ID 權杖的到期時間 (
exp宣告) 尚未超過。 - 如果您在要求中指定 hd 參數值,請確認 ID 權杖具有與 Google Cloud 機構相關聯的接受網域相符的
hd宣告。
步驟 2 到 5 只涉及字串和日期比較,相當簡單,因此我們不會在此詳細說明。
第一步較為複雜,涉及加密編譯簽章檢查。如要偵錯,可以使用 Google 的 tokeninfo 端點,與伺服器或裝置上實作的本機處理作業進行比較。假設 ID 權杖的值為 XYZ123。接著,您會取消參照 URI https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123。如果權杖簽章有效,回應會是已解碼 JSON 物件形式的 JWT 酬載。
tokeninfo 端點適合用於偵錯,但如果是正式版,請從金鑰端點擷取 Google 的公開金鑰,並在本機執行驗證。您應使用 jwks_uri 中繼資料值,從導覽文件擷取金鑰 URI。傳送至偵錯端點的要求可能會受到節流限制,或發生間歇性錯誤。
由於 Google 很少變更公開金鑰,因此您可以使用 HTTP 回應的快取指令來快取金鑰,在絕大多數情況下,本機驗證的效率會比使用 tokeninfo 端點高得多。這項驗證作業需要擷取及剖析憑證,並發出適當的密碼編譯呼叫來檢查簽章。幸好,有許多語言提供經過完善偵錯的程式庫,可協助您完成這項工作 (請參閱 jwt.io)。
取得使用者個人資料
如要取得使用者的其他設定檔資訊,您可以使用存取權杖 (應用程式在驗證流程中收到的權杖) 和 OpenID Connect 標準:
為符合 OpenID 規範,您必須在驗證要求中加入
openid profile範圍值。如要納入使用者的電子郵件地址,可以指定額外的範圍值
email。如要同時指定profile和email,您可以在驗證要求 URI 中加入下列參數:scope=openid%20profile%20email將存取權杖新增至授權標頭,並向 userinfo 端點發出 HTTPS
GET要求,您應使用userinfo_endpoint中繼資料值從探索文件擷取該端點。userinfo 回應包含使用者相關資訊,如OpenID Connect Standard Claims和導覽文件的claims_supported中繼資料值所述。使用者或其機構可以選擇提供或不提供特定欄位,因此您可能無法取得授權存取範圍內所有欄位的資訊。
導覽文件
OpenID Connect 通訊協定需要使用多個端點來驗證使用者,以及要求權杖、使用者資訊和公開金鑰等資源。
為簡化實作程序並提高彈性,OpenID Connect 允許使用「導覽文件」,這是一份位於已知位置的 JSON 文件,其中包含鍵/值組合,可提供 OpenID Connect 供應商設定的詳細資料,包括授權、權杖、撤銷、使用者資訊和公開金鑰端點的 URI。Google OpenID Connect 服務的導覽文件可從以下網址擷取:
https://accounts.google.com/.well-known/openid-configuration
如要使用 Google 的 OpenID Connect 服務,請將導覽文件 URI (https://accounts.google.com/.well-known/openid-configuration) 硬式編碼至應用程式。應用程式會擷取文件、在回應中套用快取規則,然後視需要從中擷取端點 URI。舉例來說,如要驗證使用者,程式碼會擷取 authorization_endpoint 中繼資料值 (在下方範例中為 https://accounts.google.com/o/oauth2/v2/auth),做為傳送至 Google 的驗證要求基準 URI。
以下是這類文件的範例;欄位名稱是 OpenID Connect Discovery 1.0 中指定的名稱 (請參閱該文件瞭解其含義)。這些值僅供說明之用,且可能會變更,但這些值是從最新版本的實際 Google 導覽文件複製而來:
{ "issuer": "https://accounts.google.com", "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth", "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code", "token_endpoint": "https://oauth2.googleapis.com/token", "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo", "revocation_endpoint": "https://oauth2.googleapis.com/revoke", "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs", "response_types_supported": [ "code", "token", "id_token", "code token", "code id_token", "token id_token", "code token id_token", "none" ], "subject_types_supported": [ "public" ], "id_token_signing_alg_values_supported": [ "RS256" ], "scopes_supported": [ "openid", "email", "profile" ], "token_endpoint_auth_methods_supported": [ "client_secret_post", "client_secret_basic" ], "claims_supported": [ "aud", "email", "email_verified", "exp", "family_name", "given_name", "iat", "iss", "locale", "name", "picture", "sub" ], "code_challenge_methods_supported": [ "plain", "S256" ] }
您可以快取導覽文件中的值,避免 HTTP 來回。系統會使用標準 HTTP 快取標頭,且應遵循這些標頭。
用戶端程式庫
下列用戶端程式庫與熱門架構整合,可簡化 OAuth 2.0 的實作程序:
- 適用於 Java 的 Google API 用戶端程式庫
- 適用於 Python 的 Google API 用戶端程式庫
- 適用於 .NET 的 Google API 用戶端程式庫
- 適用於 Ruby 的 Google API 用戶端程式庫
- 適用於 PHP 的 Google API 用戶端程式庫
- Google Web Toolkit 的 OAuth 2.0 程式庫
- Google Toolbox for Mac OAuth 2.0 控制器
OpenID Connect 法規遵循
Google 的 OAuth 2.0 驗證系統支援 OpenID Connect Core 規格的必要功能。任何設計為與 OpenID Connect 搭配使用的用戶端,都應與這項服務互通 (OpenID 要求物件除外)。
