上次修改日期:2025 年 9 月 10 日
總覽
本文件涵蓋透過 TS.43 電話號碼驗證,將電信業者加入 Firebase 電話號碼驗證 (FPNV) 的所有必要步驟。
術語
相關當事人
- CSP:通訊服務供應商
- 例如:行動電信業者
- 集結網站
- 應用程式端匯總器:匯總器可讓應用程式執行驗證,不必直接與電信業者互動
- 例如 Firebase 電話號碼驗證
- 中繼集結網站:支援電信業者加入應用程式集結網站的集結網站
- 元聚合器可負責為電信業者設定授權伺服器,以及/或向面向應用程式的聚合器設定授權伺服器的詳細資料
- FPNV:Firebase 電話號碼驗證
- Google 客戶技術顧問:協助電信業者加入 FPNV 的 Google 客戶技術顧問
- Android Telephony:提供 Android 上的電話號碼 API,包括供電信業者和匯總器提供 TS.43 驗證的平台
- GSMA:行動網路業者協會,負責定義規格,包括 TS.43
- CAMARA:Linux 開放原始碼專案,與 GSMA 合作定義電信業者 API
驗證條款
- PNV:電話號碼驗證
- TS.43:定義行動用戶端和伺服器與電信業者通訊時使用的 HTTP 通訊協定
- EAP-AKA:在 https://www.rfc-editor.org/rfc/rfc4187 中定義的驗證方法,不需要與使用者互動
- ECS:授權設定伺服器
- 聚合器與貨運公司溝通的入口點
- ODSA:裝置端服務啟用
- 指 ECS 提供的不同作業,可啟用裝置上的服務
- 例如:AcquireTemporaryToken、GetPhoneNumber
電信業者授權伺服器和 PNV 端點
建立必要端點
動作 1:電信業者實作下列端點,這些端點都可透過網際網路存取。如要進一步瞭解實作方式,請參閱附錄 A。
技術規定
一般效能:所有端點的正常運作時間至少應為 99.99%。
安全性:基於安全考量,電信業者端點必須符合下列規定:
- EAP-AKA 驗證權杖:必須在 1 小時內失效
- 臨時權杖:只能使用一次,5 分鐘後失效
- 選項 1 - Vanilla TS.43
- OAuth 權杖:必須在 1 小時內失效
- 選項 2 - CAMARA
- CAMARA 存取權杖:單次使用,5 分鐘後失效
API 資料品質:成功回應的內容 100% 準確 (即 MSISDN 應正確無誤)。
FPNV 支援兩種 TS.43 規格。主要差異在於 FPNV 伺服器與電信業者交換 TempToken 的方式。
選項 1 - Vanilla TS.43 實作
Android 裝置提出的要求
- EAP-AKA 端點:傳回授權權杖
- AcquireTemporaryToken 端點:提供驗證權杖,傳回 TempToken
來自 FPNV 伺服器的要求
- OAuth 2.0 端點 - OAuth 用戶端 ID/密鑰流程:提供 OAuth 用戶端 ID/密鑰,傳回 OAuth 存取權杖
- GetPhoneNumber 端點:提供 OAuth 存取權杖和 TempToken,傳回對應的電話號碼
選項 2 - 導入 CAMARA
CAMARA 實作方式與原始 TS.43 實作方式類似,但處理 FPNV 伺服器要求的端點除外。
Android 裝置提出的要求
- EAP-AKA 端點:傳回授權權杖
- AcquireTemporaryToken 端點:提供驗證權杖,傳回 TempToken
來自 FPNV 伺服器的要求
- OAuth 2.0 端點 - JWT 持有者流程:提供含有 TempToken 的 JWT,傳回 CAMARA 存取權杖
- CAMARA NumberVerification v2 端點:提供 CAMARA 存取權杖,傳回對應的電話號碼
加入 Android 電話通訊和 FPNV
電信業者測試應用程式
步驟 2:電信業者與 Google 技術客戶經理 (TAM) 聯絡,TAM 會將 FPNV 電信業者測試應用程式提供給電信業者。這個電信業者測試應用程式會模擬 FPNV 傳送的要求,但不會涉及 FPNV 伺服器。電信業者可使用這款測試應用程式,驗證端點是否正常運作。
動作 3:電信業者使用 FPNV 電信業者測試應用程式,驗證上述端點是否能正常運作。
設定必要的正式版設定
Android Config - EAP-AKA / AcquireTempToken
ACTION4:電信業者為 Android Telephony 的 EAP-AKA/AcquireTempToken 請求定義生產設定
- 設定:
- 這個電信業者的 Android 標準電信業者 ID
- TS.43 use_cases 值:
use_case=GetPhoneNumber - EAP-AKA/AcquireTempToken 的正式版授權伺服器網址
- Firebase 生產環境 x509 憑證的 SAN 和指紋
- SAN:
fpnv.googleapis.com - 指紋:
aad068c93399a22fc2b11ab58468e8cb72b8f9fc53700991799a8b764c589c7e
Firebase 設定 - 將 TempToken 換成電話
ACTION5:Firebase 憑證,用於從電信業者擷取 OAuth 權杖
- Vanilla TS.43
- 電信業者會為 FPNV 的要求建立 OAuth 用戶端 ID 和密鑰。電信業者接著會設定 OAuth 端點,針對這些憑證傳回存取權杖
- CAMARA
- Google TAM 提供 Google 的公開金鑰,因此電信業者的 OAuth 端點可以驗證 JWT 是否由 Google 簽署
步驟 6:電信業者定義 FPNV 伺服器的正式版設定,以便將 TempToken 換成手機
- 這個 MNO 的 Android 標準電信業者 ID
- Vanilla TS.43
- OAuth - 用戶端 ID/密鑰流程
- OAuth 端點網址
- OAuth 用戶端 ID/密鑰
- OAuth 範圍 (如有)
- GetPhoneNumber
- GetPhoneNumber 端點網址
- CAMARA
- OAuth - JWT 持有者流程
- OAuth 端點網址
- NumberVerification API v2
- NumberVerification 端點網址
共用憑證/設定
Firebase 電話號碼驗證
步驟 7:電信業者與 Google 技術帳戶管理員分享步驟 4 和步驟 6 的生產設定。
- [重要] 請務必使用安全的頻外 (不透過電子郵件、文件等)機制,與 Google 分享 OAuth 密鑰。這項頻外機制將由電信業者和 Google 技術支援帳戶經理 (TAM) 共同決定。
步驟 8:Google TAM 會使用電信業者測試應用程式,驗證設定是否能正常運作。驗證完成後,Google TAM 會將 OAuth 憑證儲存在 Google 安全儲存空間,並更新 FPNV 的設定,將 TempToken 換成電話 (即步驟 6 的設定)。
Android 電話
行動 9:電信業者按照「Google Open Gateway CSP Onboarding」文件 (Google TAM 會提供給電信業者) 操作。電信業者或 Google TAM 會提交 Buganizer 票證,以便加入 Android Telephony 的設定: https://issuetracker.google.com/issues/new?component=1861595&template=2168610。 這個錯誤會從 ACTION4 取得正式版設定。
如果中繼聚合器代表電視網設定 FPNV 整合,則必須提供電視網領導階層 (總監以上) 的同意聲明 (電子郵件、PDF、信件等),確認與該營運商的業務關係。之後,中繼匯總器可以代表電信業者,向 Android Telephony 提供電信業者的設定。
附件 A。詳細實作方式
區分大小寫
- HTTP 標頭「不」區分大小寫
- 不過,XML 和 JSON 格式會區分大小寫。因此,請確保要求/回應欄位與這份說明文件完全相符。
步驟 1 - EAP-AKA / AcquireTempToken
端點:EAP-AKA 和 AcquireTempToken 必須使用相同的 ECS 端點。
EAP-AKA 驗證
參考資料:TS.43 v12.0 - Section 2.8.1 -「Embedded EAP-AKA Authentication by Entitlement Configuration Server」(透過授權設定伺服器進行內嵌 EAP-AKA 驗證)。
EAP-AKA 步驟 1 - 驗證挑戰
EAP-AKA #1 - GET 要求傳送至 ECS
Android Telephony 模組會將 TS.43 EAP-AKA 要求傳送至電信業者的授權伺服器。
Android 的要求標頭
Accept:application/vnd.gsma.eap-relay.v1.0+json- 這是 GSMA 專用的 JSON 格式,不只是
application/json
- 這是 GSMA 專用的 JSON 格式,不只是
Android 的要求欄位
eap_id:請參閱 RCC.14 附錄 C。- 即
0<IMSI>@<realm>.mnc<MNC>.mcc<MCC>.3gppnetwork.org
- 即
GID1:只有在授權版本為 12.0 時才會指定app_name:編碼後的 AppName 會包含執行電話號碼驗證的用途 MD5 雜湊值:- 所有面向應用程式的聚合器要求都會有
Google-OGI的應用程式名稱
- 所有面向應用程式的聚合器要求都會有
app:應用程式 IDap2014代表電話號碼資訊terminal_vendor/model/sw_version:設為任意值;Android 不保證這些欄位包含實際裝置資訊vers:設定版本,例如 0 或 1entitlement_version:Google 會根據電信業者要求設定傳送給電信業者的授權版本- 通常
entitlement_version為 10.0 或 12.0
- 通常
EAP-AKA #1 - ECS 的回應
ECS 回應標頭
Content-Type:Android 預期回應類型會與要求中的 Accept 標頭相符- 即
application/vnd.gsma.eap-relay.v1.0+json
- 即
ECS 回應欄位
eap-relay-packet:包含 EAP 套件,遵循 RCC.14 - Section C.2
EAP-AKA 步驟 2 - 取得驗證權杖
EAP-AKA #2 - POST 要求傳送至 ECS
Android Telephony 模組隨後會將收到的 eap-relay-packet 傳回同一個端點。
Android 的要求標頭
Accept:Android 會設定兩個 Accept 標頭:application/vnd.gsma.eap-relay.v1.0+json:如果裝置需要再次傳送 EAP-AKA 要求,是指電信業者再次傳回 JSONtext/vnd.wap.connectivity-xml:指 Android 預期電信業者傳回 EAP-AKA 驗證權杖的實際格式
Content-Type:application/vnd.gsma.eap-relay.v1.0+json
Android 的要求欄位
eap-relay-packet:包含先前的 EAP-AKA 回應的 eap-relay-packet,但格式為 EAP-Response/AKA-Challenge,遵循 RFC 4817 - 第 9.2 節。
EAP-AKA #2 - ECS 的回覆
EAP-AKA 驗證成功後,電信業者會傳回驗證權杖。
ECS 回應標頭
Content-Type:Android 預期回應會與要求 Accept 標頭相符- 也就是說,Android 預期含有授權權杖的回應類型為
text/vnd.wap.connectivity-xml - 另一個 Accept 標頭
application/vnd.gsma.eap-relay.v1.0+json則用於電信業者希望 Android 執行另一個 EAP-AKA 要求的情況
- 也就是說,Android 預期含有授權權杖的回應類型為
ECS 回應欄位
TOKEN.token:包含驗證權杖TOKEN.validity:裝置收到回應後,回應有效的秒數- Google 會驗證授權權杖是否符合技術規定
AcquireTemporary Token
AcquireTempToken - 對 ECS 發出 GET 要求
Android 用戶端會使用從 EAP-AKA 收到的驗證權杖,呼叫電信業者的 AcquireTemporaryToken 端點,擷取臨時權杖。要求
- 範例:TS.43 v12.0 - Section 6.4.6 - 「AcquireTemporaryToken Request Example」(取得臨時權杖要求範例)
- AcquireTempToken 的參數與 EAP-AKA #1 類似,但有以下例外狀況:
- AcquireTempToken 也會指定
IMSI, operation和operation_targets - AcquireTempToken 未指定
EAP_ID
- AcquireTempToken 也會指定
Android 的要求標頭
Accept:Android 會設定text/vnd.wap.connectivity-xml
Android 的要求欄位
terminal_vendor/model/sw_version:Android 無法保證這些欄位包含裝置的實際資訊operation_targets- FPNV:作業目標為
GetPhoneNumber
- FPNV:作業目標為
AcquireTempToken - ECS 的回應
範例:TS.43 v12.0 - Section 6.6.6 - "AcquireTemporaryToken Response Example"
ECS 回應標頭
Content-Type:Android 預期回應類型會與要求中的 Accept 標頭相符- 即
text/vnd.wap.connectivity-xml
- 即
ECS 回應欄位
APPLICATION.TemporaryToken:FPNV 伺服器可交換電話號碼的 TemporaryTokenAPPLICATION.TemporaryTokenExpiry:到期時間,格式為 YYYY-MM-DDThh:mm:ssTZD- Google 會驗證 TempToken 的到期時間是否符合技術要求。
APPLICATION.OperationResult:請參閱 TS.43 v12.0 - Section 6.5.1- 具體來說,如果作業是
SUCCESS,則傳回 1
- 具體來說,如果作業是
步驟 2 - 換取電話號碼的 TempToken
選項 1 - Vanilla TS.43
端點:OAuth 和 GetPhoneNumber 端點可以是不同的伺服器/端點。這些端點也可能與 EAP-AKA/AcquireTempToken 端點不同。
OAuth
電信業者應按照這份 OAuth 指南操作,並向 Google 提供必要的 OAuth 資訊 (用戶端 ID、用戶端密鑰、OAuth 伺服器 URL)。
OAuth - 對電信業者驗證伺服器提出 POST 要求
FPNV 要求標頭
Authorization:FPNV 會設定Basic $BASE64_ENCODED_CREDENTIALS- 採用 Base64 編碼的憑證是 OAuth 的 Base64 編碼
$CLIENT_ID:$CLIENT_SECRET
- 採用 Base64 編碼的憑證是 OAuth 的 Base64 編碼
Content-Type:FPNV 會設定application/x-www-form-urlencodedAccept:FPNV 會設定application/json
FPNV 要求欄位
grant_type:client_credentials
POST HTTP/1.1
Host: $OAUTH_ENDPOINT
Authorization: Basic $BASE64_ENCODED_CREDENTIALS
Content-Type: application/x-www-form-urlencoded
Accept: application/json
grant_type=client_credentials
OAuth - 電信業者驗證伺服器的回應
電信業者的回應標頭
Content-Type:FPNV 預期回應類型會與要求中的 Accept 標頭相符- 即
application/json
- 即
電信業者的回應欄位
access_token:OAuth 存取權杖token_type:bearerexpires_in:OAuth 存取權杖的到期時間 (以秒為單位)- Google 會驗證 OAuth 權杖的到期時間是否符合技術規定
200 OK
Content-Type: application/json
{
"access_token": $ACCESS_TOKEN,
"token_type": "bearer",
"expires_in": $EXPIRATION_IN_SECS,
}
GetPhoneNumber
GetPhoneNumber - 對 ECS 提出 POST 要求
Google 驗證伺服器會使用 GetPhoneNumber 作業擷取電話號碼。
- 範例:TS.43 v12.0 - Section 6.4.7 - "GetPhoneNumber Request Example"
FPNV 的要求標頭
Accept:application/jsonContent-Type:application/json
FPNV 的要求欄位
requestor_id:識別呼叫 GetPhoneNumber TS.43 作業的服務- Firebase 電話號碼驗證 UUID:
191fd7cc-f7cd-4bb4-a5d2-455ae1fb9a19
- Firebase 電話號碼驗證 UUID:
temporary_token:從 AcquireTempToken 取得的 TemporaryTokenaccess_token:Google 用於向電信業者驗證的 OAuth 權杖terminal_vendor/model/sw_version:FPNV 會以任意值填入這些欄位entitlement_version:Google 會根據電信業者要求設定傳送給電信業者的授權版本- 通常
entitlement_version為 10.0 或 12.0
- 通常
app:FPNV 會設定ap2014app_name:FPNV 會為所有 FPNV 要求設定firebase- 注意:無論使用哪個匯總工具,AcquireTempToken 的
app_name都會是Google-OGI。
- 注意:無論使用哪個匯總工具,AcquireTempToken 的
operation:FPNV 會設定GetPhoneNumber
GetPhoneNumber - ECS 的回應
範例:TS.43 v12.0 - Section 6.6.7 - "GetPhoneNumber Response Example"
電信業者的回應標頭
Content-Type:FPNV 預期回應類型會與要求中的 Accept 標頭相符- 即
application/json
- 即
電信業者的回應欄位
ap2014.MSISDN:FPNV 預期電話號碼會以 E164 格式傳回- JSON 區分大小寫,因此 MSISDN 必須大寫
TemporaryToken 錯誤代碼
參照 TS.43 v12.0 第 2.8.6 節。
下表詳細說明 ECS 預期會針對 GetPhoneNumber 要求傳回給 Google 驗證伺服器的失敗回應:
情境 |
從 ECS 取得 GET/POST 回應代碼 |
第三方伺服器動作 |
要求中的參數無效或遺漏,或格式有誤 |
400 錯誤的要求 |
在下次叫用使用者時重試 / 在用戶端重新啟動後重試 |
要求中的臨時權杖無效或已過期 |
401 未獲授權 |
盡可能觸發裝置從 ECS 取得 (新的) 有效臨時權杖 |
與臨時權杖搭配使用時,作業無效 |
403 Forbidden |
在下次叫用使用者時重試 / 在用戶端重新啟動後重試 |
找不到要求的資源 |
找不到 404 |
在下次叫用使用者時重試 / 在用戶端重新啟動後重試 |
ECS 在處理要求時發生內部錯誤 |
500 內部伺服器錯誤 |
在下次叫用使用者時重試 / 在用戶端重新啟動後重試 |
選項 2 - CAMARA
端點:擷取 CAMARA 存取權杖和擷取電話號碼可能使用不同的伺服器/端點。這些端點也可能與 EAP-AKA / AcquireTempToken 端點不同。
OAuth - 擷取 CAMARA 存取權杖
Google 只會支援 CAMARA 的 JWT 持有人流程,不支援 CIBA 流程。
CAMARA 存取權杖 - 向電信業者發出 POST 要求
Google 會建立含有下列欄位的 JWT。
iss:JWT 的簽發者 (又稱用戶端 ID)- 即
firebase(實際 FPNV 整合) 或fpnv-carrier-tester-app(電信業者測試應用程式)
- 即
sub:JWT 的主體- 即
operatortoken:$TEMP_TOKEN
- 即
aud:對象;JWT 的預期收件者- 權杖端點網址 (即授權伺服器的網址)
exp:到期時間 (以秒為單位)- Google 會傳送與 CAMARA 存取權杖有效期限相符的到期時間 (請參閱技術需求)
iat:發行時間 (以秒為單位)jti:專屬 ID,可避免重播攻擊- 例如隨機產生的 UUID
scope:要求目的- 即
dpv:FraudPreventionAndDetection number-verification:device-phone-number:read
- 即
{
"iss": "firebase",
"sub": "operatortoken:ey...",
"aud": $OAUTH_ENDPOINT,
"exp": $EXPIRATION_TIME_IN_SECS,
"iat": $ISSUED_AT_TIME_IN_SECS,
"jti": $RANDOMLY_GENERATED_UUID,
"scope": "dpv:FraudPreventionAndDetection number-verification:device-phone-number:read"
}
FPNV 會使用自己的私密金鑰簽署 JWT,而電信業者可以使用對應的公開金鑰驗證 JWT。FPNV 會透過 JWKS 端點提供公開金鑰。由於 FPNV 會定期輪替公開金鑰 (例如每 30 天一次),因此電信業者應定期輪詢這個 JWKS 端點的公開金鑰 (例如每天一次)。
FPNV 的要求標頭
Content-Type:application/x-www-form-urlencodedAccept:application/json
FPNV 的要求欄位
grant_type:urn:ietf:params:oauth:grant-type:jwt-bearerassertion:上方建立的 JWT,並以 FPNV 的私密金鑰簽署- 請注意,這個 JWT 包含 TempToken
POST /token.oauth2 HTTP/1.1
Host: as.example.com
Content-Type: application/x-www-form-urlencoded
Accept: application/json
grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer
&assertion=$JWT
CAMARA 存取權杖 - 電信業者回應
電信業者的回應標頭
Content-Type:FPNV 預期回應類型會與要求中的 Accept 標頭相符- 即
application/json
- 即
電信業者的回應欄位
access_token:CAMARA 存取權杖,之後可換取電話號碼token_type:bearerexpires_in:OAuth 存取權杖的到期時間 (以秒為單位)- Google 會驗證 OAuth 權杖的到期時間是否符合技術規定
scope:要求目的- 即
dpv:FraudPreventionAndDetection number-verification:device-phone-number:read
- 即
200 OK
Content-Type: application/json
{
"access_token": $CAMARA_ACCESS_TOKEN,
"token_type": "bearer",
"expires_in": $EXPIRATION_IN_SECS,
"scope": "dpv:FraudPreventionAndDetection number-verification:device-phone-number:read"
}
CAMARA NumberVerification API v2
接著,Google 會向電信業者的 /device-phone-number 端點傳送 GET 要求,交換該 CAMARA 存取權杖。
CAMARA NumberVerification - GET Request to Carrier
FPNV 的要求標頭
Authorization:Bearer $CAMARA_ACCESS_TOKENAccept:application/json
GET /device-phone-number
Authorization: Bearer $CAMARA_ACCESS_TOKEN
Accept: application/json
Content-Type: application/json
CAMARA NumberVerification - Response from Carrier
電信業者的回應標頭
Content-Type:FPNV 預期回應類型會與要求中的 Accept 標頭相符- 即
application/json
- 即
電信業者的回應欄位
devicePhoneNumber:傳回 E164 格式的電話號碼
200 OK
Content-Type: application/json
{
"devicePhoneNumber": $PHONE_NUMBER
}