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 API Console 中設定專案,才能取得 OAuth 2.0 憑證、設定重新導向 URI,以及 (選擇性) 自訂使用者同意聲明畫面中向使用者顯示的品牌宣傳資訊,您的應用程式才能使用 Google 的 OAuth 2.0 驗證系統進行使用者登入。您也可以使用 API Console 建立服務帳戶、啟用計費功能、設定篩選及執行其他工作。詳情請參閱 Google API Console說明。
取得 OAuth 2.0 憑證
您需要 OAuth 2.0 憑證 (包含用戶端 ID 和用戶端密鑰) 來驗證使用者,並取得 Google API 的存取權。
要查看给定OAuth 2.0凭据的客户端ID和客户端密钥,请单击以下文本: 选择凭据 。在打开的窗口中,选择您的项目和所需的凭证,然后单击“ 查看” 。
或者,从API Console的“ 凭据”页面中查看您的客户端ID和客户端密钥:
- Go to the Credentials page.
- 单击您的凭证名称或铅笔( create )图标。您的客户ID和密码位于页面顶部。
設定重新導向 URI
您在 API Console 中設定的重新導向 URI 會決定 Google 回應驗證要求的位置。
要创建,查看或编辑给定OAuth 2.0凭据的重定向URI,请执行以下操作:
- Go to the Credentials page.
- 在页面的OAuth 2.0客户端ID部分中,点击一个凭据。
- 查看或编辑重定向URI。
如果“凭据”页面上没有OAuth 2.0客户端ID部分,则您的项目没有OAuth凭据。要创建一个,点击创建凭证 。
自訂使用者同意畫面
對使用者而言,OAuth 2.0 驗證體驗包含同意畫面,說明使用者發布的資訊和適用的條款。舉例來說,使用者登入時,系統可能會要求他們授予應用程式電子郵件地址和基本帳戶資訊的存取權。您可以使用 scope
參數要求這項資訊的存取權,您的應用程式會在自己的驗證要求中納入這項資訊。您也可以使用範圍來要求其他 Google API 的存取權。
使用者同意畫面也會顯示品牌名稱、標誌和首頁網址等品牌宣傳資訊。您可以透過 API Console控管品牌宣傳資訊。
要啟用項目的同意屏幕:
- 在Consent Screen page中打開Google API Console 。
- If prompted, select a project, or create a new one.
- 填寫表格,然後點擊保存 。
下列同意聲明對話方塊會顯示使用者在要求中同時顯示 OAuth 2.0 和 Google 雲端硬碟範圍時看到的內容。(這個一般對話方塊使用 Google OAuth 2.0 Playground 產生,因此不包含在 API Console中設定的品牌宣傳資訊)。

存取服務
Google 和第三方提供程式庫,讓您用來處理眾多驗證使用者實作作業、取得 Google API 存取權等實作詳細資訊。例如 Google Identity 服務和各種 Google 平台的 Google 用戶端程式庫。
如果您選擇不使用程式庫,請按照本文其餘章節中的指示操作,其中將說明可用程式庫的基礎 HTTP 要求流程。
驗證使用者
驗證使用者需要取得 ID 憑證並加以驗證。ID 憑證是 OpenID Connect 的標準功能,用於在網際網路上分享身分斷言。
「驗證伺服器」和「隱含」流程,最常用於驗證使用者並取得 ID 憑證。伺服器流程可讓應用程式的後端伺服器透過瀏覽器或行動裝置驗證使用者身分。當用戶端應用程式 (通常在瀏覽器中執行 JavaScript) 必須直接存取 API (而非透過後端伺服器),系統就會使用隱含流程。
本文說明如何執行伺服器流程來驗證使用者。由於用戶端在處理及使用權杖時會有安全性風險,隱含流程會更為複雜。如果您需要實作隱含流程,強烈建議您使用 Google Identity 服務。
伺服器流程
請務必在 API Console中設定應用程式,讓應用程式使用這些通訊協定並驗證您的使用者。當使用者嘗試登入 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
,您從 API Console Credentials page 中取得的 .response_type
,基本基本授權碼流程中的要求應為code
。(詳情請參閱response_type
)。scope
,基本要求中應為openid email
。(詳情請參閱scope
)。redirect_uri
應為您伺服器中來自 Google 的回應的 HTTP 端點。這個值必須與您在 API ConsoleCredentials page中設定的 OAuth 2.0 用戶端授權重新導向 URI 完全相同。如果這個值與已獲授權的 URI 不符,要求就會失敗並傳回redirect_uri_mismatch
錯誤。state
應包含防偽造專屬工作階段符記的值,以及使用者返回應用程式時復原內容所需的任何其他資訊 (例如起始網址)。(詳情請參閱state
)。nonce
是由應用程式產生的隨機值,會在啟用時啟用重播保護功能。login_hint
可以是使用者的電子郵件地址或sub
字串,等同於使用者的 Google ID。如果您未提供login_hint
,且使用者目前登入了,同意畫面會顯示請求,允許將使用者的電子郵件地址傳送給您的應用程式。 (詳情請參閱login_hint
)。- 使用
hd
參數,針對與特定 Google 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//oauth2.example.com/code& 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://oauth2.example.com/code?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
您必須確認從 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 |
從 API ConsoleCredentials page取得的用戶端 ID,如取得 OAuth 2.0 憑證中所述。 |
client_secret |
從 API ConsoleCredentials page取得的用戶端密鑰,如取得 OAuth 2.0 憑證中所述。 |
redirect_uri |
API ConsoleCredentials page中指定的 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//oauth2.example.com/code& 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 憑證,然後再使用該 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 |
一律 | 不得在期限內接受身分證件。以 Unix 時間 (整數秒數) 表示。 |
iat |
一律 | 核發身分證件的時間。以 Unix 時間 (整數秒數) 表示。 |
iss |
一律 | 回應核發者的核發機構識別碼。如果是 Google ID 符記,一律為 https://accounts.google.com 或 accounts.google.com 。 |
sub |
一律 | 使用者的專屬 ID,在所有 Google 帳戶中都不得重複。一個 Google 帳戶可以在不同時間點使用多個電子郵件地址,但 sub 值將維持不變。在應用程式中使用 sub 做為使用者的專屬 ID 金鑰。長度上限為 255 個區分大小寫的 ASCII 字元。 |
at_hash |
存取權杖雜湊。驗證存取憑證是否與識別憑證相連結。如果在伺服器流程中以 access_token 值核發 ID 權杖,系統一律會納入這項憑證附加資訊。此憑證可做為替代跨網站要求偽造攻擊的替代機制,但如果您遵循步驟 1 和步驟 3,就不需要驗證存取憑證。 |
|
azp |
獲得授權的簡報者 client_id 。只有在要求 ID 憑證的一方與 ID 憑證的目標對像不同時,才需要使用這項聲明。如果 Google 的混合型應用程式具有網頁應用程式和 Android 應用程式使用不同的 OAuth 2.0 client_id ,但共用相同的 Google API 專案,就有可能發生這種情況。 |
|
email |
使用者的電子郵件地址。這個值不可重複,因此不適合用來當做主鍵。只有在範圍包含 email 範圍值時才會提供。 |
|
email_verified |
如果使用者的電子郵件地址已通過驗證,傳回 True,否則傳回 False。 | |
family_name |
使用者的姓氏或名字。提供 name 憑證時,必須提供。 |
|
given_name |
使用者的姓名或名字。提供 name 憑證時,必須提供。 |
|
hd |
與使用者 Google Cloud 機構相關聯的網域。僅適用於使用者屬於 Google Cloud 機構的情況。 | |
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 進行驗證的好處之一是,您的應用程式可以在驗證使用者的同時,代表使用者 (例如 YouTube、Google 雲端硬碟、日曆或聯絡人) 使用其他 Google API。如要這麼做,請在傳送給 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 |
(必填) | 從 API ConsoleCredentials page取得的用戶端 ID 字串,如取得 OAuth 2.0 憑證中所述。 |
nonce |
(必填) | 由應用程式產生的隨機值,可啟用重播保護功能。 |
response_type |
(必填) | 如果值為 code ,系統會啟動基本授權碼流程,要求 POST 取得權杖端點才能取得權杖。如果值為 token id_token 或 id_token token ,就會啟動隱含流程,要求在重新導向 URI 中使用 JavaScript,以便從 URI #fragment ID 擷取憑證。 |
redirect_uri |
(必填) | 決定回應的傳送位置。此參數的值必須與您在 API ConsoleCredentials page 中設定的其中一個授權重新導向值 (包括 HTTP 或 HTTPS 配置、大小寫,以及結尾的「/」) 完全一致。 |
scope |
(必填) | 範圍參數必須以 如果有 如果有 除了這些 OpenID 專屬範圍之外,您的範圍引數也可以包含其他範圍值。所有範圍值都必須以空格分隔。舉例來說,如果您想讓使用者分別存取每個檔案的 Google 雲端硬碟,範圍參數就可能會是 如需可用範圍的相關資訊,請參閱 Google API 的 OAuth 2.0 範圍或您要使用的 Google API 說明文件。 |
state |
(選用,但強烈建議使用) | 通訊協定中會經過四捨五入的不透明字串;也就是說,系統會將該字串做為基本流程中的 URI 參數,以及隱式流程中的 URI
|
access_type |
(選填) | 允許的值為 offline 和 online 。效果會記錄在「離線存取」中;如要要求存取權杖,除非指定 offline 的值,否則用戶端不會收到更新權杖。 |
display |
(選填) | ASCII 字串值,用於指定授權伺服器如何顯示驗證和同意聲明使用者介面頁面。下列值是由 Google 伺服器指定且接受,但對其行為沒有影響:page 、popup 、touch 和 wap 。 |
hd |
(選填) | 簡化 Google Cloud 機構所擁有帳戶的登入程序。將 Google Cloud 機構網域 (例如 mycollege.edu) 納入之後,您就能表明帳戶選取 UI 應針對該網域中的帳戶進行最佳化。一般來說,如要針對 Google Cloud 機構帳戶進行最佳化,而不只是一個 Google Cloud 機構網域,請設定星號 ( 請勿仰賴此 UI 最佳化功能來控制誰能夠存取您的應用程式,因為用戶端要求可以修改。請務必驗證傳回的 ID 憑證是否包含符合預期 (例如 mycolledge.edu) 的 |
include_granted_scopes |
(選填) | 如果這項參數的值為 true ,且已獲授權,授權就會包含其他先前針對使用者/應用程式組合授予其他範圍的授權,請參閱漸進式授權一節。請注意,您無法針對已安裝的應用程式流程執行漸進式授權。 |
login_hint |
(選填) | 應用程式知道要嘗試驗證的使用者時,就能提供這個參數給驗證伺服器。傳遞這個提示會隱藏帳戶選擇工具,並預先填入登入表單中的電子郵件方塊,或是選取適當的工作階段 (如果使用者使用多帳戶登入),這有助於避免您的應用程式登入錯誤的使用者帳戶。這個值可以是電子郵件地址或 sub 字串,其相當於使用者的 Google ID。 |
prompt |
(選填) | 以空格分隔的字串值清單,用於指定授權伺服器是否提示使用者重新驗證和同意。可能的值包括:
如未指定任何值,且使用者先前並未授權存取,則系統會顯示同意畫面。 |
驗證 ID 憑證
除非您知道所有 ID 權杖是直接從 Google 取得,否則您必須自行驗證伺服器中的所有 ID 憑證。舉例來說,您的伺服器必須從用戶端應用程式收到任何驗證用的 ID 憑證。
以下是您將 ID 憑證傳送至伺服器的常見情況:
- 傳送需要驗證的要求 ID 憑證。該 ID 憑證會指出提出要求的使用者和取得該 ID 憑證的用戶端。
ID 符記屬於敏感性質,在攔截時可能會遭到濫用。請務必僅透過 HTTPS 傳輸權杖,且只在透過 POST 資料或要求標頭中傳送,系統才能以安全的方式處理這些權杖。如果您將 ID 憑證儲存在伺服器上,也必須以安全的方式儲存這些憑證。
ID 憑證的用途之一,就是您可以在應用程式的不同元件之間傳送 ID 憑證。這些元件可以使用 ID 憑證,透過輕量的驗證機制來驗證應用程式與使用者。但是,您「必須」使用 ID 權杖中的資訊,或將其做為使用者已驗證的宣告。
完成身分驗證程序需要完成幾個步驟:
- 確認核發者已正確簽署身分證件。系統會使用探索文件
jwks_uri
中繼資料值中指定的 URI 找到的其中一個憑證來簽署 Google 核發的憑證。 - 確認 ID 憑證中的
iss
憑證值是否等於https://accounts.google.com
或accounts.google.com
。 - 確認 ID 憑證中的
aud
憑證值是否等於應用程式的用戶端 ID。 - 請確認 ID 憑證的到期時間 (
exp
聲明) 尚未過期。 - 如果您在要求中指定 hd 參數的值,請確認 ID 憑證的
hd
聲明與與 Google Cloud 機構相關聯的接受網域相符。
步驟 2 到步驟 5 只與字串和日期的比較非常直接,因此我們不會在這裡加以詳細說明。
第一個步驟較為複雜,涉及加密編譯簽名檢查。為了進行偵錯,您可以使用 Google 的 tokeninfo
端點來比較在伺服器或裝置上執行的本機處理程序。假設您的 ID 憑證值為 XYZ123
。然後,您會取消 URI https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123
。如果權杖簽章有效,則回應會是 JWT 酬載,其已解碼的 JSON 物件格式。
tokeninfo
端點很適合用於偵錯,但在實際工作環境中,請從金鑰端點擷取 Google 的公開金鑰,並在本機執行驗證程序。您應使用 jwks_uri
中繼資料值從探索文件中擷取金鑰 URI。向偵錯端點發出的要求可能會受到限製或發生暫時性錯誤。
因為 Google 會經常變更公開金鑰,所以您可以使用 HTTP 回應的快取指令對金鑰進行快取,而且在絕大多數情況下,使用 tokeninfo
端點都能有效執行本機驗證。這項驗證需要擷取及剖析憑證,並發出適當的加密編譯呼叫來檢查簽名。幸好,我們提供多種語言的偵錯程式庫,能夠支援多種語言,詳情請參閱 jwt.io。
取得使用者個人資料
如要取得使用者的額外個人資料資訊,您可以使用存取憑證 (應用程式在驗證流程期間接收的應用程式) 和 OpenID Connect 標準:
您必須在驗證要求中加入
openid profile
範圍值,才能符合 OpenID 規定。如要加入使用者的電子郵件地址,您可以將其他範圍值
email
指定為。如要同時指定profile
和email
,您可以在驗證要求 URI 中加入下列參數:scope=openid%20profile%20email
- 將您的存取權杖新增至授權標頭,並向 Userinfo 端點發出 HTTPS
GET
要求,您應該使用userinfo_endpoint
中繼資料值從探索文件擷取。如OpenID Connect Standard Claims
以及 Discovery 文件的claims_supported
中繼資料值所述,userinfo 回應將包含使用者的相關資訊。使用者或其所屬機構可能會選擇提供或保留特定欄位,因此您可能無法針對已授權的存取範圍取得每個欄位的資訊。
探索文件
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 的實作:
OpenID Connect 法規遵循
Google 的 OAuth 2.0 驗證系統支援 OpenID Connect Core 規格的必要功能。任何可與 OpenID Connect 搭配使用的用戶端都應與這項服務互通 (OpenID 要求物件除外)。