קישור חשבונות באמצעות OAuth (Dialogflow)

סוג הקישור OAuth תומך בשני תהליכי OAuth 2.0 מקובלים בתחום, התהליכים המשתמעת וההרשאה.

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

בתהליך הקוד של ההרשאה, נדרשות שתי נקודות קצה:

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

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

הטמעה של קישור חשבון OAuth

הגדרת הפרויקט

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

  1. פותחים את Actions Console ובוחרים את הפרויקט שבו רוצים להשתמש.
  2. לוחצים על הכרטיסייה פיתוח ובוחרים באפשרות קישור חשבונות.
  3. מפעילים את המתג שלצד קישור חשבונות.
  4. בקטע יצירת חשבון, בוחרים באפשרות לא, אני רוצה לאפשר רק יצירת חשבון באתר שלי.

  5. בקטע Linking type (סוג הקישור), בוחרים באפשרות OAuth ו-Implicit (מרומז).

  6. בקטע פרטי לקוח:

    • כדי לזהות בקשות שמגיעות מ-Google, מקצים ערך ל-Client-ID שהונפק על ידי Actions to Google.
    • עליך להזין את כתובות ה-URL של נקודות הקצה Authorization ו-Token Exchange.
  1. לוחצים על שמירה.

הטמעה של שרת OAuth

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

כשהפעולה צריכה לבצע קריאה לאחד מממשקי ה-API המורשים של השירות, Google משתמשת בנקודת הקצה הזו כדי לקבל מהמשתמשים הרשאה לקרוא לממשקי ה-API האלה בשמם.

סשן זרימה מרומז של OAuth 2.0 טיפוסי ש-Google יזמה כולל את התהליך הבא:

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

טיפול בבקשות הרשאה

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

פרמטרים של נקודת קצה להרשאה
client_id מזהה הלקוח שהקצית ל-Google.
redirect_uri כתובת ה-URL שאליה שולחים את התגובה לבקשה הזו.
state ערך של ניהול ספרים שמועבר בחזרה אל Google ללא שינוי ב-URI של ההפניה האוטומטית.
response_type סוג הערך שצריך להחזיר בתגובה. בתהליך המשתמע של OAuth 2.0, סוג התגובה הוא תמיד token.

לדוגמה, אם נקודת הקצה של ההרשאה זמינה ב-https://myservice.example.com/auth, בקשה עשויה להיראות כך:

GET https://myservice.example.com/auth?client_id=GOOGLE_CLIENT_ID&redirect_uri=REDIRECT_URI&state=STATE_STRING&response_type=token

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

  1. מאמתים את הערכים client_id ו-redirect_uri כדי למנוע מתן גישה לאפליקציות לקוח לא מכוונות או שהוגדרו באופן שגוי:

    • מוודאים ש-client_id תואם למזהה הלקוח שהקציתם ל-Google.
    • מוודאים שכתובת ה-URL שצוינה בפרמטר redirect_uri מופיעה בצורה הבאה:
      https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID
      YOUR_PROJECT_ID הוא המזהה שנמצא בדף Project settings ב-Actions Console.
  2. יש לבדוק אם המשתמש מחובר לשירות שלך. אם המשתמש לא מחובר, צריך להשלים את תהליך הכניסה או ההרשמה של השירות.

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

  4. שולחים תגובת HTTP שמפנה את דפדפן המשתמש לכתובת ה-URL שצוינה בפרמטר redirect_uri. יש לכלול את כל הפרמטרים הבאים בקטע של כתובת ה-URL:

    • access_token: אסימון הגישה שיצרת עכשיו
    • token_type: המחרוזת bearer
    • state: ערך המצב של הבקשה המקורית ללא שינוי בהמשך מוצגת דוגמה לכתובת ה-URL שהתקבלה:
      https://oauth-redirect.googleusercontent.com/r/YOUR_PROJECT_ID#access_token=ACCESS_TOKEN&token_type=bearer&state=STATE_STRING

הגורם המטפל בהפניה אוטומטית מסוג OAuth 2.0 של Google יקבל את אסימון הגישה ויאשר שהערך של state לא השתנה. אחרי ש-Google תקבל אסימון גישה לשירות שלכם, Google תצרף את האסימון לקריאות הבאות לפעולה כחלק מ-AppRequest.

התחלת תהליך האימות

כדי להתחיל את תהליך האימות, תוכלו להשתמש בIntent של מסייע הכניסה לחשבון. בקטעי הקוד הבאים מוסבר איך לשלוח תשובה ב-Dialogflow וב-Actions SDK כדי להיעזר בכלי העזר הזה.

Dialogflow:

Node.js
const {dialogflow, SignIn} = require('actions-on-google');
const app = dialogflow({
  // REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
  clientId: CLIENT_ID,
});
// Intent that starts the account linking flow.
app.intent('Start Signin', (conv) => {
  conv.ask(new SignIn('To get your account details'));
});
Java
@ForIntent("Start Signin")
public ActionResponse text(ActionRequest request) {
  ResponseBuilder rb = getResponseBuilder(request);
  return rb.add(new SignIn().setContext("To get your account details")).build();
}
JSON
{
  "payload": {
    "google": {
      "expectUserResponse": true,
      "richResponse": {
        "items": [
          {
            "simpleResponse": {
              "textToSpeech": "PLACEHOLDER"
            }
          }
        ]
      },
      "userStorage": "{\"data\":{}}",
      "systemIntent": {
        "intent": "actions.intent.SIGN_IN",
        "data": {
          "@type": "type.googleapis.com/google.actions.v2.SignInValueSpec",
          "optContext": "To get your account details"
        }
      }
    }
  },
  "outputContexts": [
    {
      "name": "/contexts/_actions_on_google",
      "lifespanCount": 99,
      "parameters": {
        "data": "{}"
      }
    }
  ]
}

SDK ל-Actions:

Node.js
const {actionssdk, SignIn} = require('actions-on-google');
const app = actionssdk({
  // REPLACE THE PLACEHOLDER WITH THE CLIENT_ID OF YOUR ACTIONS PROJECT
  clientId: CLIENT_ID,
});
// Intent that starts the account linking flow.
app.intent('actions.intent.TEXT', (conv) => {
  conv.ask(new SignIn('To get your account details'));
});
Java
@ForIntent("actions.intent.TEXT")
public ActionResponse text(ActionRequest request) {
  ResponseBuilder rb = getResponseBuilder(request);
  return rb.add(new SignIn().setContext("To get your account details")).build();
}
JSON
{
  "expectUserResponse": true,
  "expectedInputs": [
    {
      "inputPrompt": {
        "richInitialPrompt": {
          "items": [
            {
              "simpleResponse": {
                "textToSpeech": "PLACEHOLDER"
              }
            }
          ]
        }
      },
      "possibleIntents": [
        {
          "intent": "actions.intent.SIGN_IN",
          "inputValueData": {
            "@type": "type.googleapis.com/google.actions.v2.SignInValueSpec",
            "optContext": "To get your account details"
          }
        }
      ]
    }
  ],
  "conversationToken": "{\"data\":{}}",
  "userStorage": "{\"data\":{}}"
}

טיפול בבקשות גישה לנתונים

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