הגנה על חשבונות משתמש באמצעות הגנה על כל החשבונות

אם האפליקציה שלכם מאפשרת למשתמשים להיכנס לחשבונות שלהם באמצעות Google, תוכלו לשפר את האבטחה של המשתמשים המשותפים האלה. לשם כך, תצטרכו להאזין להודעות אירועי האבטחה המסופקות על ידי השירות 'הגנה על כל החשבונות' ולהגיב להן.

ההתראות האלה מיידעות אותך לגבי שינויים משמעותיים בחשבונות Google של המשתמשים שלך, שעלולות להיות להן השלכות מבחינת האבטחה על החשבונות של האפליקציה שלך. לדוגמה, אם חשבון Google של משתמש נפרץ, הדבר עלול לגרום לפריצה לחשבון של המשתמש באפליקציה שלך דרך שחזור חשבון אימייל או שימוש בכניסה יחידה.

כדי לעזור לכם לצמצם את פוטנציאל הסיכון של אירועים כאלה, Google שולחת את האובייקטים של השירות שנקראים אסימוני אירועי אבטחה. האסימונים האלה חושפים מעט מאוד מידע - רק את סוג אירוע האבטחה ומתי הוא התרחש, ואת המזהה של המשתמש שהושפע - אבל אפשר להשתמש בהם כדי לפעול בהתאם. לדוגמה, אם חשבון Google של משתמש נפרץ, ניתן להשבית זמנית את התכונה 'כניסה באמצעות חשבון Google' עבור המשתמש הזה ולמנוע שליחה של הודעות אימייל לשחזור החשבון לכתובת ה-Gmail של המשתמש.

ההגנה על כל החשבונות מבוססת על תקן RISC, שפותח בקרן OpenID.

סקירה כללית

כדי להשתמש בהגנה על כל החשבונות באפליקציה או בשירות, עליכם לבצע את המשימות הבאות:

  1. מגדירים את הפרויקט ב API Console.

  2. יוצרים נקודת קצה למקבלי אירועים, שאליה Google תשלח אסימונים לאירוע אבטחה. נקודת הקצה הזו אחראית לאימות האסימונים שהיא מקבלת, ואז מגיבה לאירועי אבטחה בכל דרך שתבחרו.

  3. צריך לרשום את נקודת הקצה ב-Google כדי להתחיל לקבל אסימוני אבטחה.

דרישה מוקדמת

רק משתמשי Google שהעניקו לשירות שלכם הרשאה לגשת לפרטי הפרופיל או לכתובות האימייל שלהם יכולים לקבל אסימוני אירוע אבטחה. כדי לקבל את ההרשאה הזו, צריך לבקש את ההיקפים של profile או email. חבילות ה-SDK החדשות יותר לכניסה באמצעות חשבון Google או לכניסה באמצעות חשבון Google מדור קודם כוללות בקשה להיקפים אלה כברירת מחדל, אבל אם אתם לא משתמשים בהגדרות ברירת המחדל או אם אתם ניגשים ישירות לנקודת הקצה של OpenID, חשוב שתבקשו לפחות אחד מההיקפים האלה.

צריך להגדיר פרויקט ב- API Console

לפני שמתחילים לקבל אסימוני אבטחה, צריך ליצור חשבון שירות ולהפעיל את RISC API בפרויקטAPI Console . תצטרכו להשתמש באותו פרויקטAPI Console שדרכו אתם משתמשים כדי לגשת לשירותי Google, כמו כניסה לחשבון Google, באפליקציה שלכם.

כדי ליצור את חשבון השירות:

  1. פותחים את API Console Credentials page. כשתוצג הבקשה, בוחרים את הפרויקט API Console שדרכו אתם ניגשים לשירותי Google באפליקציה.

  2. לוחצים על יצירת פרטי כניסה > חשבון שירות.

  3. יצירת חשבון שירות חדש עם תפקיד ה'עורך'.

  4. יצירת מפתח לחשבון השירות החדש שיצרת. בוחרים את סוג מפתח ה-JSON ולוחצים על יצירה. כשתיצרו את המפתח, תוכלו להוריד קובץ JSON שכולל את פרטי הכניסה לחשבון השירות שלכם. שומרים את הקובץ הזה במקום בטוח, אבל נגיש גם לנקודת הקצה של מקבל האירוע.

גם אם אתם בדף 'פרטי הכניסה' של הפרויקט, שמרו גם את מזהי הלקוחות שבהם אתם משתמשים כדי להיכנס באמצעות חשבון Google או התכונה 'כניסה באמצעות חשבון Google' (מדור קודם). בדרך כלל יש לכם מזהה לקוח לכל פלטפורמה שאתם תומכים בה. תצטרכו את מזהי הלקוחות האלה כדי לאמת אסימוני אבטחה, כפי שמתואר בסעיף הבא.

כדי להפעיל את ה-RISC API:

  1. פותחים את דף RISC API ב-API Console. ודאו שהפרויקט שבו אתם משתמשים כדי לגשת לשירותי Google עדיין נבחר.

  2. עליכם לקרוא את תנאי ה-RISC ולוודא שאתם מבינים את הדרישות.

    אם אתם מפעילים את ה-API עבור פרויקט שבבעלות הארגון, חשוב לוודא שיש לכם הרשאה לחייב את הארגון שלכם לתנאים של RISC.

  3. יש ללחוץ על הפעלה רק אם אתם מסכימים לתנאים של RISC.

יצירת נקודת קצה לקליטת אירועים

כדי לקבל התראות על אירועי אבטחה מ-Google, צריך ליצור נקודת קצה מסוג HTTPS שמטפלת בבקשות HTTPS POST. לאחר שתרשמו את נקודת הקצה הזו (ראו למטה), Google תתחיל לפרסם נקודות קצה (endpoint) החתומות באופן וירטואלי בשם אירועי אבטחה. אסימוני JWT חתומים מכילים מידע על אירוע יחיד הקשור לאבטחה.

עבור כל אסימון אירוע אבטחה שתקבלו בנקודת הקצה, תצטרכו לאמת ולפענח את האסימון לפני שתטפלו באירוע האבטחה בהתאם לשירות שלכם. חובה לאמת את אסימון האירוע לפני הפענוח כדי למנוע מתקפות זדוניות ממשתמשים זדוניים. בקטעים הבאים מתוארות המשימות הבאות:

1. מפענחים ומאמתים את אסימון אירוע האבטחה

מכיוון שאסימוני אירועי אבטחה הם סוג ספציפי של JWT, תוכלו להשתמש בכל ספריית JWT, כמו זו שמופיעה ב-jwt.io, כדי לפענח אותן ולאמת אותן. בכל ספרייה, קוד האימות:

  1. לקבלת מזהה המנפיק של הגנה על כל החשבונות (issuer) ומזהה URI של מפתח חתימה (jwks_uri) ממסמך תצורת ה-RISC של Google&#39, שנמצא בכתובת https://accounts.google.com/.well-known/risc-configuration.
  2. בעזרת ספריית JWT לבחירתך, תוכלו להשיג את מזהה חתימת החתימה בכותרת של אסימון אירוע האבטחה.
  3. ממסמך האישור של חתימה ב-Google, מקבלים את המפתח הציבורי עם מזהה המפתח שקיבלתם בשלב הקודם. אם המסמך לא מכיל מפתח עם המזהה שחיפשתם, סביר להניח שאסימון אירוע האבטחה לא תקין ונקודת הקצה צריכה להחזיר שגיאת HTTP 400.
  4. השתמשו בספריית JWT הרצויה:
    • אסימון אירוע האבטחה חתום באמצעות המפתח הציבורי שקיבלתם בשלב הקודם.
    • תביעת הבעלות על האסימון של aud היא אחת מהאפליקציות שלך' מזהי לקוח.
    • דרישות הבעלות של האסימון iss תואמות למזהה המנפיק שקיבלת ממסמך הגילוי של RISC. שימו לב: אין צורך לאמת את תוקף האסימון (exp) כי האסימונים של אירועי אבטחה מייצגים אירועים היסטוריים, ולכן התוקף שלהם לא פג.

למשל:

Java

באמצעות Java-jwt ו-jwks-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:
                // https://console.developers.google.com/apis/credentials?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:
# https://console.developers.google.com/apis/credentials?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)

אם האסימון תקף ופוענח בהצלחה, יש להחזיר את הסטטוס 202 של HTTP. לאחר מכן, יש לטפל באירוע האבטחה המצוין באמצעות האסימון.

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"
    }
  }
}

התלונות iss ו-aud מציינות את המנפיק של האסימון (Google) ואת הנמען שאליו צריך לשלוח את האסימון (השירות שלך). אימתתם את הטענות האלה בשלב הקודם.

התלונה jti היא מחרוזת שמזהה אירוע אבטחה בודד, והיא ייחודית לזרם. תוכלו להשתמש במזהה הזה כדי לעקוב אחרי אירועי האבטחה שקיבלתם.

התלונה events מכילה מידע על אירוע האבטחה שהאסימון מייצג. התלונה הזו היא מיפוי ממזהה של סוג אירוע לתלונה של subject, שמציינת את המשתמש לגבי האירוע הזה ופרטים נוספים על האירוע שאולי יהיה זמין.

התלונה subject מזהה משתמש מסוים עם מספר חשבון Google הייחודי של המשתמש (sub). מספר החשבון הזה ב-Google הוא אותו מזהה (sub) שנמצא באסימונים של מזהה JWT שהונפקו על ידי הספרייה החדשה 'כניסה באמצעות חשבון Google' (JavaScript, HTML), ספריית כניסה באמצעות חשבון Google מדור קודם, או התחברות באמצעות. כאשר subject_type של התלונה הוא id_token_claims, הוא עשוי לכלול גם שדה email עם כתובת האימייל של המשתמש.

יש להשתמש במידע שצוין בתלונה מסוג events כדי לבצע את הפעולה המתאימה לגבי סוג האירוע בחשבון של המשתמש שצוין.

מזהי אסימוני OAuth

באירועי OAuth לגבי אסימונים ספציפיים, סוגי המזהים token subject מכילים את השדות הבאים:

  • 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 APIs אחרים, יש למחוק את אסימוני ה-OAuth של המשתמש שאחסנת.

https://schemas.openid.net/secevent/oauth/event-type/token-revoked למידע על מזהי אסימונים, אפשר לעיין בקטע מזהי אסימון OAuth

חובה: אם מאחסנים את אסימון הרענון המתאים, מוחקים אותו ומבקשים מהמשתמשים להביע הסכמה שוב בפעם הבאה שיהיה צורך באסימון גישה.

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-purged הצעות: צריך למחוק את החשבון של המשתמש או לספק לו שיטת כניסה חלופית.
https://schemas.openid.net/secevent/risc/event-type/account-credential-change-required מומלץ: יש לחפש פעילות חשודה בשירות שלך ולנקוט פעולה מתאימה.
https://schemas.openid.net/secevent/risc/event-type/verification מדינה=state מוצע: רישום שהתקבל אסימון אסימון.

אירועים משוכפלים ואירועים שפספסת

במסגרת ההגנה על כל החשבונות ננסה למסור מחדש אירועים שלדעתה לא נמסרו. לכן ייתכן שלפעמים תקבלו את אותו אירוע כמה פעמים. אם הדבר עלול לגרום לפעולות חוזרות ונשנות שעלולות לגרום אי נוחות למשתמשים, כדאי להשתמש בתלונה jti (שהיא מזהה ייחודי לאירוע) כדי לבטל את הכפילויות באירועים. יש כלים חיצוניים כמו Google Cloud Dataflow שיכולים לעזור לכם להוציא משימוש את זרימת הנתונים.

חשוב לדעת: האירועים נשלחים עם ניסיונות מוגבלים נוספים, כך שאם המקלט שלכם מושבת למשך זמן רב, יכול להיות שתפספסו אירועים מסוימים באופן סופי.

רישום המקבל

כדי להתחיל לקבל אירועי אבטחה, צריך לרשום את נקודת הקצה של המקלט באמצעות ה-RISC API. לקריאות ל-RISC API צריך להיות מלווה באסימון הרשאה.

תקבלו אירועי אבטחה רק למשתמשי האפליקציה. לכן, כדי שתוכלו לבצע באפליקציה מראש את ההגדרה המתוארת בהמשך, אתם צריכים להגדיר מראש מסך הסכמה ב-OAuth בפרויקט GCP.

1. יצירת אסימון הרשאה

כדי ליצור אסימון הרשאה ל-RISC API, יוצרים JWT עם התלונות הבאות:

{
  "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-jwt וספריית האימות של Google:

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')

אפשר להשתמש באסימון ההרשאות הזה לביצוע קריאות ל-API של RISC למשך שעה. לאחר פקיעת התוקף של האסימון, צריך ליצור אסימון חדש כדי להמשיך לבצע קריאות ל-API של RISC.

2. קריאה ל-RISC Configuration configuration API

עכשיו, אחרי שיש לכם אסימון הרשאה, תוכלו להשתמש ב-RISC API כדי להגדיר את השידור של אירוע האבטחה בפרויקט, כולל רישום של נקודת הקצה למקלט.

לשם כך, צריך לשלוח בקשת HTTPS מ-HTTPS אל https://risc.googleapis.com/v1beta/stream:update, ולציין את נקודת הקצה (endpoint) ואת הסוגים של אירועי האבטחה שמעניינים אותך:

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, מקור הנתונים של האירוע הוגדר בהצלחה ונקודת הקצה של המקבל אמורה להתחיל לקבל אסימוני אירועי אבטחה. הקטע הבא מתאר איך אפשר לבדוק את ההגדרות האישיות של הסטרימינג ואת נקודת הקצה כדי לוודא שהכול פועל כמו שצריך.

קבלה ועדכון של תצורת השידור הנוכחית

אם בעתיד תרצו לשנות את תצורת השידור, תוכלו לעשות זאת על ידי שליחת בקשת GET מורשית אל https://risc.googleapis.com/v1beta/stream כדי לקבל את תצורת השידור הנוכחית, שינוי גוף התגובה ולאחר מכן שליחה של התצורה שהשתנה ל-https://risc.googleapis.com/v1beta/stream:update כמתואר למעלה.

הפסקה והפעלה מחדש של זרם האירועים

אם בשלב כלשהו יהיה צורך להפסיק את שידור האירוע מ-Google, יש לשלוח בקשת POST מורשית ל-https://risc.googleapis.com/v1beta/stream/status:update עם { "status": "disabled" } בגוף ההודעה. כשהשידור מושבת, Google לא שולחת אירועים לנקודת הקצה ולא מאחסנת אירועי אבטחה כאשר הם מתרחשים. כדי להפעיל מחדש את שידור האירוע, צריך לפרסם את { "status": "enabled" } באותה נקודת קצה.

3. אופציונלי: בודקים את הגדרות השידור

כדי לוודא שתצורת השידור ונקודת הקצה של המקבל פועלים כראוי, אתם יכולים לשלוח אסימון אימות דרך שידור האירוע. האסימון הזה יכול להכיל מחרוזת ייחודית שתוכלו להשתמש בה כדי לאמת שהאסימון התקבל בנקודת הקצה שלכם.

כדי לבקש אסימון אימות, יש להגיש בקשת HTTP POST מורשית אל 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()))

אם הבקשה תאושר, אסימון האימות יישלח לנקודת הקצה שרשמתם. לדוגמה, אם נקודות הקצה (endpoint) מטפלות באסימוני האימות, פשוט מתעדים אותן, ולאחר מכן בודקים את היומנים כדי לוודא שהאסימון התקבל.

הפניה לקוד שגיאה

ניתן להחזיר את השגיאות הבאות על ידי RISC API:

קוד שגיאה הודעת שגיאה הצעות לפעולות
160 ההגדרה של מקור הנתונים חייבת להכיל שדה $fieldname. הבקשה שלך בנקודת הקצה https://risc.googleapis.com/v1beta/stream:update לא חוקית או שלא ניתן לנתח אותה. עליך לכלול את $fieldname בבקשה שלך.
401 לא מורשה. ההרשאה נכשלה. חשוב לוודא שצירפת אסימון הרשאה לבקשה, ושהאסימון תקף ושאין תוקף פג בו.
163 נקודת הקצה למשלוח חייבת להיות כתובת URL מסוג HTTPS. נקודת הקצה למסירה (כלומר, נקודת הקצה שאליה יישלחו אירועי RISC) חייבת להיות HTTPS. אנחנו לא שולחים אירועי RISC לכתובות URL של HTTP.
163 בהגדרת השידור הקיימת אין שיטת הצגה תואמת למפרט של RISC. הפרויקט ב-Google Cloud חייב להיות עם תצורת RISC. אם השימוש ב-Firebase מופעל, וכניסה באמצעות חשבון Google מופעלת, Firebase ינהל את ה-RISC לפרויקט. לא תהיה לך אפשרות ליצור תצורה מותאמת אישית. אם לא נעשה שימוש בכניסה באמצעות חשבון Google לפרויקט Firebase שלך, יש להשבית אותו ולנסות לעדכן אותו לאחר שעה.
163 הפרויקט לא נמצא. יש לוודא שנעשה שימוש בחשבון השירות המתאים לפרויקט הנכון. יכול להיות שיש לך חשבון שירות שמשויך לפרויקט שנמחק. כאן מוסבר איך לראות את כל חשבונות השירות שמשויכים לפרויקט.
163 לחשבון השירות צריכות להיות הרשאות עריכה בפרויקט. יש להיכנס למסוף Google Cloud Platform של הפרויקט ולתת לחשבון השירות שנותן הרשאת עריכה/בעלים לפרויקט לפי ההוראות האלה.
163 יש להפעיל ממשקי API לניהול שידורים רק דרך חשבון שירות. בקישור הבא מוסבר איך אפשר להתקשר ל-Google APIs באמצעות חשבון שירות.
163 נקודת הקצה להעברה לא שייכת לאף אחד מהדומיינים של הפרויקט. לכל פרויקט יש קבוצה של דומיינים מורשים. אם נקודת הקצה להעברה (כלומר, נקודת הקצה (endpoint) שציפית לקבל בה את אירועי RISC) אינה מתארחת באחד מהם, עליך להוסיף את הדומיין של נקודת הקצה לקבוצה.
163 כדי להשתמש ב-API הזה, צריך להגדיר לפחות לקוח OAuth אחד בפרויקט. RISC פועל רק אם יוצרים אפליקציה שתומכת בכניסה באמצעות חשבון Google. החיבור הזה דורש לקוח OAuth. אם לפרויקט שלך אין לקוחות OAuth, סביר להניח שה-RISC לא יועיל לך. מידע נוסף על השימוש של Google ב-OAuth לממשקי ה-API שלנו.
163

סטטוס לא נתמך.

סטטוס לא חוקי.

בשלב זה, אנחנו תומכים רק בסטטוסים "enabled" ו-"disabled".
404

לפרויקט אין תצורת RISC.

לפרויקט אין תצורת RISC קיימת, אין אפשרות לעדכן את הסטטוס.

יש להתקשר לנקודת הקצה https://risc.googleapis.com/v1beta/stream:update כדי ליצור הגדרה חדשה לשידור.
4XX/5XX לא ניתן לעדכן את הסטטוס. מידע נוסף זמין בהודעת השגיאה המפורטת.

היקפי אסימון גישה

אם תחליטו להשתמש באסימוני גישה לאימות ה-RISC API, אלה ההיקפים שהאפליקציה שלכם צריכה לבקש:

נקודת קצה (endpoint) היקף
https://risc.googleapis.com/v1beta/stream/status https://www.googleapis.com/auth/risc.status.readonly או https://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.readonly או https://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 עם התג #secEvent.