透過跨帳戶防護功能保護使用者帳戶

如果您的應用程式可讓使用者透過 Google 登入帳戶, 這些共用使用者來監控及回應 Cross-Account Protection 服務提供的安全性事件通知。

我們發送這些通知,提醒您以下問題的 Google 帳戶有重大變更: 這通常也會對帳戶安全性造成影響 舉例來說,如果使用者的 Google 帳戶遭到入侵, 可能導致使用者透過電子郵件與您的應用程式遭到盜用 帳戶救援或使用單一登入。

為降低這類事件的潛在風險,Google 會將您的 稱為安全性事件符記這些符記 資訊—只有安全性事件的類型和發生時間, 以及受影響的使用者的 ID 回應。舉例來說,假設使用者的 Google 帳戶是 您可以針對該使用者暫時停用「使用 Google 帳戶登入」功能, 防止系統將帳戶救援電子郵件傳送至使用者的 Gmail 地址。

跨帳戶防護功能是以 RISC 標準, OpenID Foundation。

總覽

如要為您的應用程式或服務使用跨帳戶防護功能,您必須先完成 幾項工作:

  1. 在 中設定專案。

  2. 建立事件接收器端點,Google 會將安全性事件傳送到該端點 符記這個端點負責驗證其接收的權杖 就能以偏好的方式回應安全性事件

  3. 向 Google 註冊您的端點,即可開始接收安全性事件權杖。

修課條件

只有在已授予您相關權限的 Google 使用者的情況下,您才會收到安全性事件權杖 服務存取個人資料或電子郵件地址的權限。個人中心 要求 profileemail 範圍來取得這項權限。更新 使用 Google 帳戶登入或舊版 根據預設,Google 登入 SDK 會要求這些範圍,但 如果不使用預設設定,或您使用 Google 的 OpenID 直接連結端點,確保 您至少要求其中一個範圍。

在 中設定專案

您必須建立服務,才能開始接收安全性事件權杖 並在服務帳戶中啟用 RISC API 專案。請務必使用與 用來存取的專案 在應用程式中使用 Google 登入等 Google 服務。

如何建立服務帳戶:

  1. 開啟 。系統提示時,請選擇 。

  2. 按一下「Create credentials」(建立憑證) >服務帳戶

  3. 建立新的服務帳戶並指派 RISC 設定管理員角色 (roles/riscconfigs.admin)。 只要追蹤 這些操作說明

  4. 為新建立的服務帳戶建立金鑰。選擇 JSON 金鑰 輸入後請點選「建立」。金鑰建立完成後 您將下載內含服務帳戶的 JSON 檔案 憑證請將這個檔案存放在安全的地方,但也方便 事件接收器端點

,瞭解如何調查及移除這項存取權。

瀏覽專案的「憑證」頁面時,請注意用戶端 「使用 Google 帳戶登入」或「Google 登入」(舊版) 使用的 ID。一般來說,每個 導入。您需要這些用戶端 ID 才能驗證安全性事件 符記,如下一節所述。

如何啟用 RISC API:

  1. 開啟 RISC API 頁面, 。確認您使用的專案 但無法存取 Google 服務。

  2. 閱讀《RISC 條款》,並確保您瞭解規定。

    如果您要為機構擁有的專案啟用 API,請確認 您有權約束貴機構遵守 RISC 條款。

  3. 除非您同意《RISC 條款》,否則請點選「啟用」

建立事件接收器端點

如要接收 Google 傳送的安全性事件通知,請建立 HTTPS 端點 處理 HTTPS POST 要求的情況註冊這個端點後 (請見下方說明), Google 會開始發布經加密簽署的字串,稱為「安全性事件」 這個端點安全性事件權杖是經過簽署的 JWT,其中包含 單一安全性相關事件的相關資訊。

針對您在端點收到的每個安全性事件權杖,先驗證並 ,然後視需要處理安全性事件 課程中也會快速介紹 Memorystore 這是 Google Cloud 的全代管 Redis 服務在解碼前驗證事件符記仍然「必要」 不受惡意人士的惡意攻擊下列各節說明這些工作:

1. 解碼並驗證安全性事件權杖

安全性事件權杖是特定類型的 JWT,因此您可以使用 使用 JWT 程式庫 (例如 jwt.io 上的程式庫) 進行解碼 進行驗證無論使用哪個程式庫,您的權杖驗證碼都必須執行 包括:

  1. 取得跨帳戶防護核發機構 ID (issuer) 和簽署金鑰 Google RISC 設定文件的憑證 URI (jwks_uri), 網址是 https://accounts.google.com/.well-known/risc-configuration
  2. 使用您選擇的 JWT 程式庫,從標頭取得簽署金鑰 ID 設定安全事件權杖
  3. 在 Google 的簽署金鑰憑證文件中,透過 您在上一個步驟中取得的金鑰 ID。如果文件不含索引鍵 並找到相關資訊,則可能是安全性事件權杖 無效,且您的端點應傳回 HTTP 錯誤 400。
  4. 使用您選擇的 JWT 程式庫驗證下列事項:
    • 使用安全性事件權杖進行簽署時,系統會使用您在 上一個步驟
    • 權杖的 aud 憑證附加資訊是您的應用程式用戶端 ID
    • 權杖的 iss 憑證附加資訊與您取得的核發機構 ID 相符 RISC 探索文件 請注意,您不需要驗證符記的到期日 (exp),因為 安全性事件權杖代表歷史事件,因此沒有使用期限。

例如:

Java

使用 java-jwtjwks-rsa-java

public DecodedJWT validateSecurityEventToken(String token) {
    DecodedJWT jwt = null;
    try {
        // In a real implementation, get these values from
        // https://accounts.google.com/.well-known/risc-configuration
        String issuer = "accounts.google.com";
        String jwksUri = "https://www.googleapis.com/oauth2/v3/certs";

        // Get the ID of the key used to sign the token.
        DecodedJWT unverifiedJwt = JWT.decode(token);
        String keyId = unverifiedJwt.getKeyId();

        // Get the public key from Google.
        JwkProvider googleCerts = new UrlJwkProvider(new URL(jwksUri), null, null);
        PublicKey publicKey = googleCerts.get(keyId).getPublicKey();

        // Verify and decode the token.
        Algorithm rsa = Algorithm.RSA256((RSAPublicKey) publicKey, null);
        JWTVerifier verifier = JWT.require(rsa)
                .withIssuer(issuer)
                // Get your apps' client IDs from the API console:
                // ?project=_
                .withAudience("123456789-abcedfgh.apps.googleusercontent.com",
                              "123456789-ijklmnop.apps.googleusercontent.com",
                              "123456789-qrstuvwx.apps.googleusercontent.com")
                .acceptLeeway(Long.MAX_VALUE)  // Don't check for expiration.
                .build();
        jwt = verifier.verify(token);
    } catch (JwkException e) {
        // Key not found. Return HTTP 400.
    } catch (InvalidClaimException e) {

    } catch (JWTDecodeException exception) {
        // Malformed token. Return HTTP 400.
    } catch (MalformedURLException e) {
        // Invalid JWKS URI.
    }
    return jwt;
}

Python

import json
import jwt       # pip install pyjwt
import requests  # pip install requests

def validate_security_token(token, client_ids):
    # Get Google's RISC configuration.
    risc_config_uri = 'https://accounts.google.com/.well-known/risc-configuration'
    risc_config = requests.get(risc_config_uri).json()

    # Get the public key used to sign the token.
    google_certs = requests.get(risc_config['jwks_uri']).json()
    jwt_header = jwt.get_unverified_header(token)
    key_id = jwt_header['kid']
    public_key = None
    for key in google_certs['keys']:
        if key['kid'] == key_id:
            public_key = jwt.algorithms.RSAAlgorithm.from_jwk(json.dumps(key))
    if not public_key:
        raise Exception('Public key certificate not found.')
        # In this situation, return HTTP 400

    # Decode the token, validating its signature, audience, and issuer.
    try:
        token_data = jwt.decode(token, public_key, algorithms='RS256',
                                options={'verify_exp': False},
                                audience=client_ids, issuer=risc_config['issuer'])
    except:
        raise
        # Validation failed. Return HTTP 400.
    return token_data

# Get your apps' client IDs from the API console:
# ?project=_
client_ids = ['123456789-abcedfgh.apps.googleusercontent.com',
              '123456789-ijklmnop.apps.googleusercontent.com',
              '123456789-qrstuvwx.apps.googleusercontent.com']
token_data = validate_security_token(token, client_ids)

如果權杖有效且已順利解碼,則傳回 HTTP 狀態 202。 接著,處理憑證指出的安全性事件。

2. 處理安全性事件

解碼時,安全性事件符記會如以下範例所示:

{
  "iss": "https://accounts.google.com/",
  "aud": "123456789-abcedfgh.apps.googleusercontent.com",
  "iat": 1508184845,
  "jti": "756E69717565206964656E746966696572",
  "events": {
    "https://schemas.openid.net/secevent/risc/event-type/account-disabled": {
      "subject": {
        "subject_type": "iss-sub",
        "iss": "https://accounts.google.com/",
        "sub": "7375626A656374"
      },
      "reason": "hijacking"
    }
  }
}

issaud 憑證附加資訊會指出權杖 (Google) 和 權杖的指定接收者 (您的服務)。您已在 上一個步驟

jti 憑證附加資訊是可識別單一安全性事件的字串, 專屬於這個串流您可以用這個 ID 追蹤哪些安全性事件 。

events 憑證附加資訊包含權杖的安全性事件相關資訊 代表的本質上這項著作權聲明是事件類型 ID 與 subject 的對應關係 聲明,指出此事件疑慮,以及指定 可能有哪些事件的詳細資料。

subject 聲明會以使用者獨特的 Google 識別特定使用者 帳戶 ID (sub)。這個 Google 帳戶 ID 與憑證中的 ID 相同 (sub) 中新版「使用 Google 帳戶登入」功能所核發的 JWT ID 權杖 (JavaScript) 、HTML) 資料庫、舊版 Google 登入資料庫,或是 OpenID Connect。當 subject_type 的 聲明為 id_token_claims,也可能包含 email 欄位, 電子郵件地址。

請根據 events 著作權聲明中的資訊採取適當行動 事件類型。

OAuth 權杖 ID

對於個別權杖的 OAuth 事件,權杖主體 ID 類型包含下列欄位:

  • token_type:僅支援 refresh_token

  • token_identifier_alg:如要瞭解可能的值,請參閱下表。

  • token:請參閱下表。

token_identifier_alg 符記
prefix 權杖的前 16 個字元。
hash_base64_sha512_sha512 使用 SHA-512 取得的權杖雙重雜湊。

如果與這些事件整合,建議依據您的符記建立索引 以確保快速比對結果。

支援的事件類型

跨帳戶防護功能支援下列類型的安全性事件:

事件類型 屬性 回應方式
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked 必要:請將目前的 公開工作階段。
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked

必要:如果是 Google 登入權杖,請終止 以及目前開啟的工作階段此外,您可以建議使用者 設定替代的登入方式。

建議做法:如果權杖是用於存取其他 Google API,請刪除 您儲存的任何使用者 OAuth 權杖

https://schemas.openid.net/secevent/oauth/event-type/token-revoked OAuth 權杖 ID 部分請參閱 權杖 ID

必要:如果您儲存了對應的更新權杖,請將其刪除 ,並要求使用者在下次需要存取權杖時重新提供同意聲明。

https://schemas.openid.net/secevent/risc/event-type/account-disabled reason=hijacking,
reason=bulk-account

必填:如果帳戶遭到停用的原因 hijacking,結束使用者帳戶,以便重新確保帳戶安全 以及目前開啟的工作階段

建議:如果帳戶遭到停用的原因 bulk-account,分析使用者在服務中的活動以及 以決定適當的後續行動

建議:如未說明原因,請在該層級停用 Google 登入 使用與 使用者的 Google 帳戶 (通常是 Gmail 帳戶)。 為使用者提供其他登入方式。

https://schemas.openid.net/secevent/risc/event-type/account-enabled 建議做法:為使用者重新啟用 Google 登入功能並重新啟用 透過使用者的 Google 帳戶電子郵件地址進行帳戶救援。
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required 建議:留意服務中的可疑活動,並採取因應措施 採取適當的行動
https://schemas.openid.net/secevent/risc/event-type/verification state=state 建議:記錄已收到測試權杖的記錄。

重複和錯過的活動

跨帳戶防護功能會試著重新傳送偵測到的事件 沒傳送。因此,您有時可能會收到相同的事件 以便重複使用如果這可能造成您 使用者,請考慮使用 jti 憑證附加資訊 (這是使用者 事件) 來卸除事件。您也可以利用 Google Cloud 等外部工具 Dataflow,也許可協助您執行 清除 Dataflow 設定檔

請注意,系統會傳送事件,但重試次數有限。如果您的接收器停止運作, 您可能會永久錯過某些活動。

註冊接收器

如要開始接收安全性事件,請使用 RISC API。對 RISC API 的呼叫必須隨附授權權杖。

您只會收到應用程式使用者的安全性事件,因此您必須先設定 OAuth 同意畫面 執行這些步驟。

1. 產生授權權杖

如要產生 RISC API 的授權權杖,請使用 以下聲明:

{
  "iss": SERVICE_ACCOUNT_EMAIL,
  "sub": SERVICE_ACCOUNT_EMAIL,
  "aud": "https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService",
  "iat": CURRENT_TIME,
  "exp": CURRENT_TIME + 3600
}

使用服務帳戶的私密金鑰簽署 JWT,您可以在 建立服務帳戶金鑰時下載的 JSON 檔案。

例如:

Java

使用 java-jwtGoogle 的驗證程式庫

public static String makeBearerToken() {
    String token = null;
    try {
        // Get signing key and client email address.
        FileInputStream is = new FileInputStream("your-service-account-credentials.json");
        ServiceAccountCredentials credentials =
               (ServiceAccountCredentials) GoogleCredentials.fromStream(is);
        PrivateKey privateKey = credentials.getPrivateKey();
        String keyId = credentials.getPrivateKeyId();
        String clientEmail = credentials.getClientEmail();

        // Token must expire in exactly one hour.
        Date issuedAt = new Date();
        Date expiresAt = new Date(issuedAt.getTime() + 3600000);

        // Create signed token.
        Algorithm rsaKey = Algorithm.RSA256(null, (RSAPrivateKey) privateKey);
        token = JWT.create()
                .withIssuer(clientEmail)
                .withSubject(clientEmail)
                .withAudience("https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService")
                .withIssuedAt(issuedAt)
                .withExpiresAt(expiresAt)
                .withKeyId(keyId)
                .sign(rsaKey);
    } catch (ClassCastException e) {
        // Credentials file doesn't contain a service account key.
    } catch (IOException e) {
        // Credentials file couldn't be loaded.
    }
    return token;
}

Python

import json
import time

import jwt  # pip install pyjwt

def make_bearer_token(credentials_file):
    with open(credentials_file) as service_json:
        service_account = json.load(service_json)
        issuer = service_account['client_email']
        subject = service_account['client_email']
        private_key_id = service_account['private_key_id']
        private_key = service_account['private_key']
    issued_at = int(time.time())
    expires_at = issued_at + 3600
    payload = {'iss': issuer,
               'sub': subject,
               'aud': 'https://risc.googleapis.com/google.identity.risc.v1beta.RiscManagementService',
               'iat': issued_at,
               'exp': expires_at}
    encoded = jwt.encode(payload, private_key, algorithm='RS256',
                         headers={'kid': private_key_id})
    return encoded

auth_token = make_bearer_token('your-service-account-credentials.json')

這個授權權杖可用於進行一小時的 RISC API 呼叫。時間 憑證過期,請產生新的憑證,以繼續進行 RISC API 呼叫。

2. 呼叫 RISC 串流設定 API

取得授權權杖後,就可以使用 RISC API 來設定 您專案的安全性事件串流,包括註冊接收端 端點

方法是向 https://risc.googleapis.com/v1beta/stream:update 發出 HTTPS POST 要求。 指定接收方端點和安全性類型 您感興趣的活動:

POST /v1beta/stream:update HTTP/1.1
Host: risc.googleapis.com
Authorization: Bearer AUTH_TOKEN

{
  "delivery": {
    "delivery_method":
      "https://schemas.openid.net/secevent/risc/delivery-method/push",
    "url": RECEIVER_ENDPOINT
  },
  "events_requested": [
    SECURITY_EVENT_TYPES
  ]
}

例如:

Java

public static void configureEventStream(final String receiverEndpoint,
                                        final List<String> eventsRequested,
                                        String authToken) throws IOException {
    ObjectMapper jsonMapper = new ObjectMapper();
    String streamConfig = jsonMapper.writeValueAsString(new Object() {
        public Object delivery = new Object() {
            public String delivery_method =
                    "https://schemas.openid.net/secevent/risc/delivery-method/push";
            public String url = receiverEndpoint;
        };
        public List<String> events_requested = eventsRequested;
    });

    HttpPost updateRequest = new HttpPost("https://risc.googleapis.com/v1beta/stream:update");
    updateRequest.addHeader("Content-Type", "application/json");
    updateRequest.addHeader("Authorization", "Bearer " + authToken);
    updateRequest.setEntity(new StringEntity(streamConfig));

    HttpResponse updateResponse = new DefaultHttpClient().execute(updateRequest);
    Header[] responseContentTypeHeaders = updateResponse.getHeaders("Content-Type");
    StatusLine responseStatus = updateResponse.getStatusLine();
    int statusCode = responseStatus.getStatusCode();
    HttpEntity entity = updateResponse.getEntity();
    // Now handle response
}

// ...

configureEventStream(
        "https://your-service.example.com/security-event-receiver",
        Arrays.asList(
                "https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required",
                "https://schemas.openid.net/secevent/risc/event-type/account-disabled"),
        authToken);

Python

import requests

def configure_event_stream(auth_token, receiver_endpoint, events_requested):
    stream_update_endpoint = 'https://risc.googleapis.com/v1beta/stream:update'
    headers = {'Authorization': 'Bearer {}'.format(auth_token)}
    stream_cfg = {'delivery': {'delivery_method': 'https://schemas.openid.net/secevent/risc/delivery-method/push',
                               'url': receiver_endpoint},
                  'events_requested': events_requested}
    response = requests.post(stream_update_endpoint, json=stream_cfg, headers=headers)
    response.raise_for_status()  # Raise exception for unsuccessful requests

configure_event_stream(auth_token, 'https://your-service.example.com/security-event-receiver',
                       ['https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required',
                        'https://schemas.openid.net/secevent/risc/event-type/account-disabled'])

如果要求傳回 HTTP 200,表示事件串流設定成功 ,您的接收端端點應該會開始接收安全性事件權杖。 下一節將說明如何測試串流設定和端點 才能確認一切運作正常

取得並更新目前的串流設定

如果你日後想修改串流設定,可以選擇 因此,只要向 https://risc.googleapis.com/v1beta/stream 提出授權的 GET 要求,即可取得 現有的串流設定、修改回應主體,然後將 POST 已將設定改回 https://risc.googleapis.com/v1beta/stream:update (如上所述)。

停止並繼續事件串流

如果您需要從 Google 停止活動串流,請授權 POST 向 { "status": "disabled" } 要求 https://risc.googleapis.com/v1beta/stream/status:update 。直播停用期間,Google 不會傳送活動 不會緩衝處理發生的安全性事件。目的地: 重新啟用事件串流,將 { "status": "enabled" } 發布至相同端點。

3. 選用:測試串流設定

您可以檢查串流設定和接收器端點是否正常運作 透過活動串流傳送驗證權杖以正確整合。 此權杖可包含不重複的字串,可用來驗證 已成功收到憑證如要使用這個流程,請務必 訂閱 https://schemas.openid.net/secevent/risc/event-type/verification 事件類型。

如要索取驗證權杖,請向 https://risc.googleapis.com/v1beta/stream:verify。在要求主體中指定 識別字串:

{
  "state": "ANYTHING"
}

例如:

Java

public static void testEventStream(final String stateString,
                                   String authToken) throws IOException {
    ObjectMapper jsonMapper = new ObjectMapper();
    String json = jsonMapper.writeValueAsString(new Object() {
        public String state = stateString;
    });

    HttpPost updateRequest = new HttpPost("https://risc.googleapis.com/v1beta/stream:verify");
    updateRequest.addHeader("Content-Type", "application/json");
    updateRequest.addHeader("Authorization", "Bearer " + authToken);
    updateRequest.setEntity(new StringEntity(json));

    HttpResponse updateResponse = new DefaultHttpClient().execute(updateRequest);
    Header[] responseContentTypeHeaders = updateResponse.getHeaders("Content-Type");
    StatusLine responseStatus = updateResponse.getStatusLine();
    int statusCode = responseStatus.getStatusCode();
    HttpEntity entity = updateResponse.getEntity();
    // Now handle response
}

// ...

testEventStream("Test token requested at " + new Date().toString(), authToken);

Python

import requests
import time

def test_event_stream(auth_token, nonce):
    stream_verify_endpoint = 'https://risc.googleapis.com/v1beta/stream:verify'
    headers = {'Authorization': 'Bearer {}'.format(auth_token)}
    state = {'state': nonce}
    response = requests.post(stream_verify_endpoint, json=state, headers=headers)
    response.raise_for_status()  # Raise exception for unsuccessful requests

test_event_stream(auth_token, 'Test token requested at {}'.format(time.ctime()))

如果要求成功,驗證權杖會傳送至您所在的端點 註冊成功。舉例來說,如果您的端點透過 只是記錄記錄,您可以檢查記錄,確認該權杖 。

錯誤代碼參考資料

RISC API 可能會傳回下列錯誤:

錯誤代碼 錯誤訊息 建議採取的動作
400 串流設定必須包含 $fieldname 欄位。 您對 https://risc.googleapis.com/v1beta/stream:update 端點的要求無效或 剖析。請在要求中附上「$fieldname」。
401 未經授權。 無法提供授權,請務必附上 授權權杖,且權杖有效 且未過期
403 傳送端點必須是 HTTPS 網址。 您的放送端點 (亦即您希望 RISC 事件使用的端點 ) 必須是 HTTPS。我們不會將 RISC 事件傳送至 HTTP 網址。
403 現有串流設定的提交方式不符合規格要求 RISC 方法。 您的 Google Cloud 專案必須已有 RISC 設定。如果 您正在使用 Firebase 且已啟用 Google 登入功能,Firebase 將會 管理專案的 RISC。您將無法建立自訂指標 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定如果您的 Firebase 專案不是使用 Google 登入功能, 請停用這個功能,然後試著在一小時後再次嘗試更新。
403 找不到專案。 請確認您使用正確的服務帳戶取得所需協助 專案。你可能正在使用與已刪除的服務相關聯的服務帳戶 專案。學習新知 如何查看與專案相關聯的所有服務帳戶
403 服務帳戶需要相關權限,才能存取 RISC 設定 前往專案的 指派「RISC Configuration 管理員」角色 (roles/riscconfigs.admin) 呼叫該服務帳戶 追蹤 請參閱這篇文章中的操作說明。
403 串流管理 API 只應由服務帳戶呼叫。 以下是進一步說明 如何透過服務帳戶呼叫 Google API
403 傳送端點不屬於您專案的任何網域。 每項專案都有一組 授權網域 如果您的交付端點(即預期 RISC 事件) 會放送到) 並非代管的項目,您必須在其中新增 提供給端點的網域
403 如要使用這個 API,您的專案必須至少設定一個 OAuth 用戶端。 您必須建構支援 RISC 的應用程式 Google 登入。 這個連線需要 OAuth 用戶端。如果您的專案沒有 OAuth 那麼 RISC 可能對您沒有幫助。瞭解詳情 關於 Google 對 OAuth 的使用 Google API
403

不支援的狀態。

狀態無效。

我們僅支援串流狀態「enabled」和 「disabled」。
404

專案沒有 RISC 設定。

專案目前沒有 RISC 設定,無法更新狀態。

呼叫 https://risc.googleapis.com/v1beta/stream:update 端點,建立新的串流設定。
4XX/5XX 無法更新狀態。 詳情請查看詳細的錯誤訊息。

存取權杖範圍

如果您決定使用存取權杖驗證 RISC API,則這些 是應用程式必須要求的範圍:

端點 範圍
https://risc.googleapis.com/v1beta/stream/status https://www.googleapis.com/auth/risc.status.readonlyhttps://www.googleapis.com/auth/risc.status.readwrite
https://risc.googleapis.com/v1beta/stream/status:update https://www.googleapis.com/auth/risc.status.readwrite
https://risc.googleapis.com/v1beta/stream https://www.googleapis.com/auth/risc.configuration.readonlyhttps://www.googleapis.com/auth/risc.configuration.readwrite
https://risc.googleapis.com/v1beta/stream:update https://www.googleapis.com/auth/risc.configuration.readwrite
https://risc.googleapis.com/v1beta/stream:verify https://www.googleapis.com/auth/risc.verify

需要協助嗎?

首先,請查看我們的錯誤代碼參考資料部分。如果您仍然 如有任何問題,請前往 Stack Overflow 張貼問題,並加上 #SecEvents 標記之前。