Google 的 OAuth 2.0 API 可用於驗證及授權。本文件說明採用 OpenID Connect 規格的 OAuth 2.0 驗證實作,並已通過 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 用戶端程式庫,適用於各種平台。
如果您選擇不使用程式庫,請按照本文其餘部分的操作說明,說明可用程式庫的 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 端點。這個值必須與 OAuth 2.0 用戶端的其中一個已授權重新導向 URI 完全相符,而您在 API Console Credentials page中設定該用戶端。如果這個值與已授權的 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 Console Credentials page取得的用戶端 ID,如取得 OAuth 2.0 憑證中所述。 |
client_secret |
您從 API Console Credentials page取得的用戶端密鑰,如取得 OAuth 2.0 憑證中所述。 |
redirect_uri |
在 API Console
Credentials 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 |
包含由 Google 數位簽署的使用者識別資訊的 JWT。 |
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 權杖可能含有下列欄位 (稱為「claims」):
版權聲明 | 已提供 | 說明 |
---|---|---|
aud |
一律 | 此 ID 權杖的目標對象。此 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 字元。 |
at_hash |
存取權杖雜湊。提供存取權杖與身分權杖連結的驗證。如果 ID 權杖是在伺服器流程中使用 access_token 值核發,系統一律會包含這項憑證附加資訊。這項聲明可做為替代機制來防範跨網站偽造攻擊,但如果您已遵循步驟 1 和步驟 3,則無須驗證存取權杖。 |
|
azp |
授權簡報者的 client_id 。只有在要求 ID 權杖的一方與 ID 權杖的目標對像不同時,才需要這項聲明。例如,在 Google 混合式應用程式方面,網頁應用程式和 Android 應用程式有不同的 OAuth 2.0 client_id ,但共用相同的 Google API 專案。 |
|
email |
使用者的電子郵件地址。這個值可能不適用於這位使用者,也無法當做主鍵使用。只有在範圍包含 email 範圍值時才會提供。 |
|
email_verified |
如果使用者的電子郵件地址已通過驗證,則為「是」;否則傳回「否」。 | |
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 進行驗證的其中一項優點是,在您驗證使用者時,您的應用程式就能取得代表使用者使用其他 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 |
(必填) | 您從 API Console Credentials page取得的用戶端 ID 字串,如取得 OAuth 2.0 憑證中所述。 |
nonce |
(必填) | 應用程式產生的隨機值,用來啟用重播防護功能。 |
response_type |
(必填) | 如果值為 code ,請啟動基本授權碼流程,要求權杖端點需要 POST 才能取得權杖。如果值為 token id_token 或 id_token token ,會啟動隱含流程,要求在重新導向 URI 上使用 JavaScript,以便從 URI #fragment ID 擷取權杖。 |
redirect_uri |
(必填) | 決定回應傳送至的位置。此參數的值必須與您在 API Console Credentials 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 最佳化功能控制哪些使用者能存取應用程式。請務必validate傳回的 ID 權杖具備與預期相符的 |
include_granted_scopes |
(選填) | 如果提供這個參數的值為 true ,且授權要求獲得接受,授權會包含其他範圍,因此先前授予使用者/應用程式組合的任何授權;請參閱增量授權。請注意,您無法透過「已安裝的應用程式」流程執行漸進式授權。 |
login_hint |
(選填) | 如果應用程式知道要驗證的使用者為何,便可提供這個參數,向驗證伺服器的提示。傳送這項提示會關閉帳戶選擇工具,並在登入表單中預先填入電子郵件方塊,或是選取適當的工作階段 (如果使用者使用多重登入功能),可避免應用程式登入錯誤的使用者帳戶時發生問題。這個值可以是電子郵件地址或 sub 字串,相當於使用者的 Google ID。 |
prompt |
(選填) | 以空格分隔的字串值清單,指定授權伺服器是否提示使用者進行重新驗證和同意。可能的值包括:
如果未指定任何值,且使用者先前未獲得授權,系統會顯示同意畫面。 |
驗證 ID 權杖
除非您知道伺服器是由 Google 直接提供,否則您必須驗證伺服器上的所有 ID 權杖。舉例來說,您的伺服器必須驗證從用戶端應用程式收到的任何 ID 權杖是否已通過驗證。
以下是將 ID 權杖傳送至伺服器的常見情況:
- 傳送 ID 權杖並附上需要驗證的要求。ID 權杖可讓您瞭解提出要求的特定使用者和獲得該 ID 權杖的用戶端。
ID 權杖屬於敏感性質,如果遭到攔截,可能會遭到誤用。您必須確保這些權杖是透過 HTTPS 傳輸,而且只能透過 POST 資料或在要求標頭中傳輸,以安全的方式處理這些權杖。如果您將 ID 權杖儲存在伺服器上,也必須妥善保管。
ID 權杖的一大優點是,您可以將 ID 權杖傳遞至應用程式的不同元件。這些元件可以使用 ID 權杖做為驗證應用程式和使用者的簡易驗證機制。不過,您必須先驗證 ID,才能使用 ID 權杖中的資訊,或做為使用者已驗證的斷言。
驗證 ID 權杖需要幾個步驟:
- 確認核發機構正確簽署 ID 權杖。Google 核發的權杖是使用探索文件
jwks_uri
中繼資料值中指定的其中一個憑證進行簽署。 - 確認 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
。如果權杖簽章有效,回應就會是已解碼 JSON 物件形式的 JWT 酬載。
tokeninfo
端點適用於偵錯,但如果是實際工作環境,請從金鑰端點擷取 Google 的公開金鑰,然後在本機執行驗證。您應使用 jwks_uri
中繼資料值從探索文件擷取金鑰 URI。向偵錯端點發出的要求可能會受到限製或發生間歇性錯誤。
由於 Google 只會經常變更公開金鑰,因此您可以使用 HTTP 回應的快取指令進行快取。在大多數情況下,比起使用 tokeninfo
端點,在大多數情況下都能以更有效率的方式執行本機驗證。這項驗證需要擷取及剖析憑證,並執行適當的加密編譯呼叫來檢查簽名。幸運的是,完整偵錯的程式庫支援多種語言,可以完成這項工作 (請參閱 jwt.io)。
取得使用者個人資料
如要取得使用者的其他個人資料資訊,您可以使用存取權杖 (應用程式是在驗證流程中接收) 和 OpenID Connect 標準:
您必須在驗證要求中加入
openid profile
範圍值,才能符合 OpenID 規範。如要納入使用者的電子郵件地址,您可以指定
email
的其他範圍值。如要同時指定profile
和email
,您可以在驗證要求 URI 中加入下列參數:scope=openid%20profile%20email
- 將存取權杖新增至授權標頭,並向使用者資訊端點發出 HTTPS
GET
要求。您應使用userinfo_endpoint
中繼資料值,從探索文件中擷取這項資訊。userinfo 回應包含使用者的相關資訊,如OpenID Connect Standard Claims
和探索文件的claims_supported
中繼資料值中所述。使用者或其機構可能會選擇提供或保留特定欄位,因此您可能無法針對授權的存取權範圍取得每個欄位的資訊。
探索文件
OpenID Connect 通訊協定必須使用多個端點來驗證使用者,以及要求取得權杖、使用者資訊和公開金鑰等資源。
為了簡化實作程序並增加靈活性,OpenID Connect 允許使用「探索」文件。OpenID 文件是位於知名位置的 JSON 文件,內含鍵/值組合,其中提供有關 OpenID Connect 供應商設定的詳細資訊,包括授權、權杖、撤銷、使用者資訊和公開金鑰端點的 URI。 您可以從以下位置擷取 Google OpenID Connect 服務的 Discovery 文件:
https://accounts.google.com/.well-known/openid-configuration
如要使用 Google 的 OpenID Connect 服務,應將 Discovery 文件 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 Discovery 文件複製而來:
{ "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 要求物件除外)。