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

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

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

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

הגנה בין חשבונות מבוססת על תקן RISC , שפותח ב-OpenID Foundation.

סקירה כללית

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

  1. הגדר את הפרויקט שלך ב- API Console.

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

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

תְנַאִי מוּקדָם

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

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

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

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

  1. פתח את ה- API ConsoleCredentials page . כשתתבקש, בחר בפרויקטAPI Consoleשבו אתה משתמש כדי לגשת לשירותי Google באפליקציה שלך.

  2. לחץ על צור אישורים > חשבון שירות .

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

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

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

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

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

  2. קרא את תנאי RISC וודא שאתה מבין את הדרישות.

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

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

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

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

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

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

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

  1. קבל את מזהה המנפיק ( issuer ) ואת ה-URI של אישור מפתח חתימה ( jwks_uri ) ממסמך התצורה של RISC של Google, אותו תוכל למצוא בכתובת https://accounts.google.com/.well-known/risc-configuration .
  2. באמצעות ספריית JWT לבחירתך, קבל את מזהה מפתח החתימה מהכותרת של אסימון אירוע האבטחה.
  3. ממסמך אישור מפתח החתימה של גוגל, קבל את המפתח הציבורי עם מזהה המפתח שקיבלת בשלב הקודם. אם המסמך אינו מכיל מפתח עם המזהה שאתה מחפש, סביר להניח שאסימון אירוע האבטחה אינו חוקי, ונקודת הקצה שלך אמורה להחזיר שגיאת 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;
}

פִּיתוֹן

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)

אם האסימון תקף ופוענח בהצלחה, החזר את סטטוס 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"
    }
  }
}

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

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

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

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

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

סוגי אירועים נתמכים

הגנה בין חשבונות תומכת בסוגים הבאים של אירועי אבטחה:

סוג אירוע תכונות איך להגיב
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked נדרש : אבטח מחדש את החשבון של המשתמש על ידי סיום ההפעלות הפתוחות שלו.
https://schemas.openid.net/secevent/oauth/event-type/tokens-revoked

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

הצעה : אם האסימון מיועד לגישה לממשקי API אחרים של Google, מחק כל אחד מאסימוני ה-OAuth של המשתמש שאחסנת.

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

חובה : אם הסיבה שהחשבון הושבת הייתה hijacking , אבטח מחדש את החשבון של המשתמש על ידי סיום ההפעלות הפתוחות שלו.

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

הצעה : אם לא סופקה סיבה, השבת את Google Sign-in עבור המשתמש והשבת את שחזור החשבון באמצעות כתובת הדוא"ל המשויכת לחשבון 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 שעשויים לעזור לך לבצע את זרימת ה-Dup Dataflow.

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

רשום את המקלט שלך

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

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

פִּיתוֹן

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. קרא לממשק API של תצורת זרם RISC

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

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

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

פִּיתוֹן

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 לא שולחת אירועים לנקודת הקצה שלך ואינה מחסנת אירועי אבטחה כשהם מתרחשים. כדי להפעיל מחדש את זרם האירועים, POST { "status": "enabled" } לאותה נקודת קצה.

3. אופציונלי: בדוק את תצורת הסטרימינג שלך

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

כדי לבקש אסימון אימות, שלח בקשת HTTPS 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);

פִּיתוֹן

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 נקודת הקצה של המסירה חייבת להיות כתובת URL של HTTPS. נקודת הקצה של המסירה שלך (כלומר נקודת הקצה שאליה אתה מצפה שאירועי RISC יימסרו) חייבת להיות HTTPS. אנחנו לא שולחים אירועי RISC לכתובות URL של HTTP.
403 לתצורת הזרם הקיימת אין שיטת מסירה תואמת למפרט עבור RISC. לפרויקט Google Cloud שלך כבר חייבת להיות תצורת RISC. אם אתה משתמש ב-Firebase והפעלת Google Sign-In, Firebase ינהל את RISC עבור הפרויקט שלך; לא תוכל ליצור תצורה מותאמת אישית. אם אינך משתמש ב-Google Sign-In עבור פרויקט Firebase שלך, השבת אותו ולאחר מכן נסה לעדכן שוב לאחר שעה.
403 הפרויקט לא נמצא. ודא שאתה משתמש בחשבון השירות הנכון עבור הפרויקט הנכון. ייתכן שאתה משתמש בחשבון שירות המשויך לפרויקט שנמחק. למד כיצד לראות את כל חשבונות השירות המשויכים לפרויקט .
403 חשבון שירות חייב להיות בעל הרשאות עורך בפרויקט שלך. עבור אל מסוף Google Cloud Platform של הפרויקט שלך והענק לחשבון השירות שמבצע את עורך השיחות/בעלים הרשאה לפרויקט שלך על ידי ביצוע ההוראות האלה .
403 יש לקרוא לממשקי API לניהול זרמים רק על ידי חשבון שירות. הנה מידע נוסף על איך אתה יכול לקרוא לממשקי API של Google עם חשבון שירות .
403 נקודת הקצה של המסירה אינה שייכת לאף אחד מהדומיינים של הפרויקט שלך. לכל פרויקט יש קבוצה של דומיינים מורשים. אם נקודת הקצה של המסירה שלך (כלומר נקודת הקצה שאליה אתה מצפה שאירועי RISC יועברו) אינה מתארחת באחד מהם, אנו דורשים שתוסיף את הדומיין של נקודת הקצה לקבוצה זו.
403 כדי להשתמש ב-API זה לפרויקט שלך צריך להגדיר לפחות לקוח OAuth אחד. RISC פועל רק אם אתה בונה אפליקציה שתומכת ב-Google Sign In . חיבור זה דורש לקוח OAuth. אם לפרויקט שלך אין לקוחות OAuth, סביר להניח ש-RISC לא יהיה שימושי עבורך. למידע נוסף על השימוש של Google ב-OAuth עבור ממשקי ה-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.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 עם התג #SecEvents .