الربط السلس باستخدام OAuth وتسجيل الدخول بحساب Google

نظرة عامة

تضيف ميزة الربط المُبسَّط لميزة "تسجيل الدخول باستخدام حساب Google" المستندة إلى OAuth ميزة "تسجيل الدخول باستخدام حساب Google" إلى ربط OAuth. يقدّم ذلك تجربة ربط سلسة لمستخدمي Google، كما يتيح إنشاء الحسابات، ما يسمح للمستخدم بإنشاء حساب جديد على خدمتك باستخدام حسابه على Google.

لإجراء عملية ربط الحساب باستخدام بروتوكول OAuth وميزة "تسجيل الدخول باستخدام حساب Google"، اتّبِع الخطوات العامة التالية:

  1. أولاً، اطلب من المستخدم الموافقة على الوصول إلى ملفه الشخصي على Google.
  2. استخدِم المعلومات الواردة في ملفه الشخصي للتحقّق مما إذا كان حساب المستخدم متوفّرًا.
  3. بالنسبة إلى المستخدمين الحاليين، عليك ربط الحسابات.
  4. إذا لم تتمكّن من العثور على مطابقة لمستخدم Google في نظام المصادقة، عليك التحقّق من صحة الرمز المميّز للهوية الذي تم تلقّيه من Google. يمكنك بعد ذلك إنشاء مستخدم استنادًا إلى معلومات الملف الشخصي الواردة في رمز التعريف.
يعرض هذا الشكل خطوات ربط حساب المستخدم على Google باستخدام مسار الربط المُبسَّط. تعرض لقطة الشاشة الأولى كيفية اختيار المستخدم لتطبيقك للربط به. تسمح لقطة الشاشة الثانية للمستخدم بتأكيد ما إذا كان لديه حساب حالي على خدمتك أم لا. تسمح لقطة الشاشة الثالثة للمستخدم باختيار حساب Google الذي يريد ربطه. تعرض لقطة الشاشة الرابعة تأكيد ربط حساب المستخدم على Google بتطبيقك. وتعرض لقطة الشاشة الخامسة حساب مستخدم تم ربطه بنجاح في تطبيق Google.

الشكل 1: ربط الحساب على هاتف المستخدم باستخدام ميزة "الربط الميسّر"

متطلبات ميزة "الربط الميسّر"

تنفيذ خادم OAuth

يجب أن تتيح نقطة نهاية تبادل الرموز المميّزة نوايا check وcreate وget. يوضّح الجدول أدناه الخطوات التي تم إكمالها خلال عملية ربط الحساب ويشير إلى وقت استدعاء النوايا المختلفة:

  1. هل لدى المستخدم حساب في نظام المصادقة؟ (يحدد المستخدم ذلك من خلال اختيار "نعم" أو "لا")
    1. نعم : هل يستخدم المستخدم عنوان البريد الإلكتروني المرتبط بحسابه على Google لتسجيل الدخول إلى منصتك؟ (يحدد المستخدم ذلك عن طريق اختيار "نعم" أو "لا")
      1. نعم : هل لدى المستخدم حساب مطابق في نظام المصادقة؟ (يتم الاتصال بالرقم check intent للتأكيد)
        1. نعم : يتمّ استدعاء get intent ويتمّ ربط الحساب إذا تمّ عرض النيّة بنجاح.
        2. لا، هل تريد إنشاء حساب جديد؟ (يحدد المستخدم ذلك عن طريق اختيار "نعم" أو "لا")
          1. نعم : يتمّ استدعاء create intent ويتمّ ربط الحساب إذا تمّ عرض نية الإنشاء بنجاح.
          2. لا : يتم بدء عملية Web OAuth، ويتم توجيه المستخدم إلى المتصفّح، ويتم منح المستخدم خيار الربط ببريد إلكتروني مختلف.
      2. لا : يتم تفعيل مسار Web OAuth، ويتم توجيه المستخدم إلى المتصفّح، ويتم منح المستخدم خيار الربط ببريد إلكتروني مختلف.
    2. لا : هل لدى المستخدم حساب مطابق في نظام المصادقة؟ (يتم الاتصال بالرقم check intent للتأكيد)
      1. نعم : يتمّ استدعاء get intent ويتمّ ربط الحساب إذا تمّ عرض النيّة بنجاح.
      2. لا : يتمّ استدعاء create intent ويتمّ ربط الحساب إذا تمّ عرض نية الإنشاء بنجاح.

检查现有用户账号(检查 intent)

在用户同意访问其 Google 个人资料后,Google 会发送 请求,其中包含 Google 用户身份的已签名断言。通过 断言包含的信息包括用户的 Google 账号 ID、 姓名和电子邮件地址为您的 Google Cloud 控制台配置的令牌交换端点 项目处理该请求。

如果您的身份验证中已有相应的 Google 账号 系统时,您的令牌交换端点会返回 account_found=true。如果 Google 账号与现有用户不匹配,您的令牌交换端点 返回“HTTP 404 Not Found”错误以及 account_found=false

请求的格式如下:

POST /token HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=check&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

您的令牌交换端点必须能够处理以下参数:

令牌端点参数
intent 对于这些请求,此参数的值为 check
grant_type 所交换的令牌的类型。对于这类请求 参数的值为 urn:ietf:params:oauth:grant-type:jwt-bearer
assertion 一个 JSON Web 令牌 (JWT),提供 Google 用户身份。JWT 包含的信息包括用户 Google 账号 ID、姓名和电子邮件地址。
client_id 您分配给 Google 的客户 ID。
client_secret 您分配给 Google 的客户端密钥。

如需响应 check intent 请求,您的令牌交换端点必须执行以下步骤:

  • 验证和解码 JWT 断言。
  • 检查您的身份验证系统中是否已存在该 Google 账号。
التحقق من صحة تأكيد JWT وفك ترميزه

يمكنك التحقق من صحة تأكيد JWT وفك ترميزه باستخدام مكتبة فك ترميز JWT بلغتك. استخدام مفاتيح Google العامة، متاحة في JWK أو PEM، للتأكّد من توقيع الرمز المميز.

عند فك ترميز النص، يظهر تأكيد JWT على النحو التالي:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

بالإضافة إلى التحقّق من توقيع الرمز المميّز، تأكَّد من أنّ التأكيد جهة الإصدار (الحقل iss) هي https://accounts.google.com، بحيث يمكن لشريحة الجمهور (الحقل aud) هو معرّف العميل الذي تم تعيينه، ولم تنتهِ صلاحية الرمز المميّز. (حقل exp).

باستخدام الحقول email وemail_verified وhd، يمكنك تحديد ما إذا كان تستضيف Google عناوين البريد الإلكتروني وموثوقًا بها. في الحالات التي تواجه فيها Google موثوقية المستخدم المعروف حاليًا بأنه صاحب الحساب الشرعي ويمكنك تخطي كلمة المرور أو طرق التحديات الأخرى. بخلاف ذلك، فإن هذه الطرق يمكن استخدامها للتحقّق من الحساب قبل ربطه

الحالات التي تكون فيها Google موثوقة:

  • السمة email هي اللاحقة @gmail.com، وهذا حساب Gmail.
  • email_verified صحيح وتم ضبط hd، هذا حساب G Suite.

يمكن للمستخدمين التسجيل للحصول على حسابات Google بدون استخدام Gmail أو G Suite. فعندما لا يحتوي email على اللاحقة @gmail.com وhd غير موجود في Google موثوقة وكلمة المرور أو طرق التحقق الأخرى للتحقق المستخدم. يمكن أن يكون email_verified صحيحًا أيضًا لأن Google تحققت في البداية من صحة المستخدم عند إنشاء حساب Google، ولكن ملكية الجهة الخارجية ربما تغير حساب بريدك الإلكتروني منذ ذلك الحين.

检查您的身份验证系统中是否已存在该 Google 账号

请检查以下任一条件是否成立:

  • Google 账号 ID(可在断言的 sub 字段中找到)位于您的用户中 数据库。
  • 断言中的电子邮件地址与用户数据库中的用户匹配。

如果满足上述任一条件,则表明用户已注册。在这种情况下 返回如下所示的响应:

HTTP/1.1 200 Success
Content-Type: application/json;charset=UTF-8

{
  "account_found":"true",
}

如果 Google 账号 ID 和 断言与您的数据库中的用户匹配,该用户尚未注册。在 在这种情况下,您的令牌交换端点需要返回 HTTP 404 错误 指定 "account_found": "false",如以下示例所示:

HTTP/1.1 404 Not found
Content-Type: application/json;charset=UTF-8

{
  "account_found":"false",
}

التعامل مع الربط التلقائي (تحقيق النية)

بعد أن يمنح المستخدِم موافقته على الوصول إلى ملفه الشخصي في Google، ترسل Google طلب يتضمن تأكيدًا موقَّعًا على هوية مستخدم Google. تشير رسالة الأشكال البيانية يحتوي تأكيد البيانات على معلومات تشتمل على رقم تعريف حساب المستخدم على Google، والاسم وعنوان البريد الإلكتروني. نقطة نهاية تبادل الرموز المميّزة التي تم ضبطها المشروع أن يتعامل مع هذا الطلب.

في حال توفُّر حساب Google المناسب في المصادقة فإن نقطة نهاية تبادل الرمز المميز تقوم بإرجاع رمز مميز للمستخدم. إذا كانت لا يتطابق حساب Google مع مستخدم حالي، نقطة نهاية تبادل الرموز المميّزة تعرض الخطأ linking_error وعرض login_hint اختياري.

يكون الطلب بالشكل التالي:

POST /token HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&intent=get&assertion=JWT&scope=SCOPES&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

يجب أن تتمكّن نقطة نهاية تبادل الرموز المميّزة من معالجة المَعلمات التالية:

مَعلمات نقطة نهاية الرمز المميّز
intent بالنسبة إلى هذه الطلبات، تكون قيمة هذه المَعلمة هي get.
grant_type تمثّل هذه السمة نوع الرمز المميّز الذي يتم تبادله. بالنسبة لهذه الطلبات، سيتم المعلَمة urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion يشير هذا المصطلح إلى رمز JSON المميّز للويب (JWT) ويقدِّم تأكيدًا موقَّعًا على بيانات وهوية المستخدم. يحتوي JWT على معلومات تتضمن عنوان URL الخاص رقم تعريف حساب Google والاسم وعنوان البريد الإلكتروني
scope اختياري: أي نطاقات تم ضبط Google فيها للطلب منها المستخدمين.
client_id معرِّف العميل الذي عيّنته لـ Google.
client_secret سر العميل الذي خصّصته لـ Google.

للردّ على طلبات intent لـ get، يجب أن تنفِّذ نقطة نهاية تبادل الرموز المميّزة الخطوات التالية:

  • التحقق من صحة تأكيد JWT وفك ترميزه
  • تحقَّق مما إذا كان حساب Google متوفّرًا من قبل في نظام المصادقة.
التحقق من صحة تأكيد JWT وفك ترميزه

يمكنك التحقق من صحة تأكيد JWT وفك ترميزه باستخدام مكتبة فك ترميز JWT بلغتك. استخدام مفاتيح Google العامة، متاحة في JWK أو PEM، للتأكّد من توقيع الرمز المميز.

عند فك ترميز النص، يظهر تأكيد JWT على النحو التالي:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

بالإضافة إلى التحقّق من توقيع الرمز المميّز، تأكَّد من أنّ التأكيد جهة الإصدار (الحقل iss) هي https://accounts.google.com، بحيث يمكن لشريحة الجمهور (الحقل aud) هو معرّف العميل الذي تم تعيينه، ولم تنتهِ صلاحية الرمز المميّز. (حقل exp).

باستخدام الحقول email وemail_verified وhd، يمكنك تحديد ما إذا كان تستضيف Google عناوين البريد الإلكتروني وموثوقًا بها. في الحالات التي تواجه فيها Google موثوقية المستخدم المعروف حاليًا بأنه صاحب الحساب الشرعي ويمكنك تخطي كلمة المرور أو طرق التحديات الأخرى. بخلاف ذلك، فإن هذه الطرق يمكن استخدامها للتحقّق من الحساب قبل ربطه

الحالات التي تكون فيها Google موثوقة:

  • السمة email هي اللاحقة @gmail.com، وهذا حساب Gmail.
  • email_verified صحيح وتم ضبط hd، هذا حساب G Suite.

يمكن للمستخدمين التسجيل للحصول على حسابات Google بدون استخدام Gmail أو G Suite. فعندما لا يحتوي email على اللاحقة @gmail.com وhd غير موجود في Google موثوقة وكلمة المرور أو طرق التحقق الأخرى للتحقق المستخدم. يمكن أن يكون email_verified صحيحًا أيضًا لأن Google تحققت في البداية من صحة المستخدم عند إنشاء حساب Google، ولكن ملكية الجهة الخارجية ربما تغير حساب بريدك الإلكتروني منذ ذلك الحين.

التأكّد من توفّر حساب Google في نظام المصادقة

تحقق مما إذا كان أي من الشروط التالية صحيحًا:

  • رقم تعريف حساب Google، الوارد في حقل sub في التأكيد، موجود في حساب المستخدم. قاعدة البيانات.
  • يتطابق عنوان البريد الإلكتروني الوارد في التأكيد مع مستخدم في قاعدة بيانات المستخدم الخاصة بك.

في حال العثور على حساب للمستخدم، عليك إصدار رمز دخول وعرض القيم في كائن JSON في نص استجابة HTTPS، كما في المثال التالي:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",
  "refresh_token": "REFRESH_TOKEN",
  "expires_in": SECONDS_TO_EXPIRATION
}

في بعض الحالات، قد يتعذّر على المستخدم ربط الحساب استنادًا إلى الرمز المميّز للمعرّف. إذا كان لأي سبب من الأسباب، تحتاج نقطة نهاية تبادل الرمز المميز إلى الرد باستخدام HTTP 401 يحدد الخطأ error=linking_error، كما يبيِّن المثال التالي:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

عندما تتلقّى Google ردًّا بالخطأ 401 مع linking_error، ترسل Google المستخدِم إلى نقطة نهاية التفويض مع استخدام login_hint كمَعلمة. تشير رسالة الأشكال البيانية إكمال المستخدم لربط الحساب باستخدام مسار ربط OAuth في المتصفِّح

Handle account creation via Google Sign-In (create intent)

When a user needs to create an account on your service, Google makes a request to your token exchange endpoint that specifies intent=create.

The request has the following form:

POST /token HTTP/1.1
Host: oauth2.example.com
Content-Type: application/x-www-form-urlencoded

response_type=token&grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer&scope=SCOPES&intent=create&assertion=JWT&client_id=GOOGLE_CLIENT_ID&client_secret=GOOGLE_CLIENT_SECRET

Your token exchange endpoint must able to handle the following parameters:

Token endpoint parameters
intent For these requests, the value of this parameter is create.
grant_type The type of token being exchanged. For these requests, this parameter has the value urn:ietf:params:oauth:grant-type:jwt-bearer.
assertion A JSON Web Token (JWT) that provides a signed assertion of the Google user's identity. The JWT contains information that includes the user's Google Account ID, name, and email address.
client_id The client ID you assigned to Google.
client_secret The client secret you assigned to Google.

The JWT within the assertion parameter contains the user's Google Account ID, name, and email address, which you can use to create a new account on your service.

To respond to the create intent requests, your token exchange endpoint must perform the following steps:

  • Validate and decode the JWT assertion.
  • Validate user information and create new account.
التحقق من صحة تأكيد JWT وفك ترميزه

يمكنك التحقق من صحة تأكيد JWT وفك ترميزه باستخدام مكتبة فك ترميز JWT بلغتك. استخدام مفاتيح Google العامة، متاحة في JWK أو PEM، للتأكّد من توقيع الرمز المميز.

عند فك ترميز النص، يظهر تأكيد JWT على النحو التالي:

{
  "sub": "1234567890",      // The unique ID of the user's Google Account
  "iss": "https://accounts.google.com",        // The assertion's issuer
  "aud": "123-abc.apps.googleusercontent.com", // Your server's client ID
  "iat": 233366400,         // Unix timestamp of the assertion's creation time
  "exp": 233370000,         // Unix timestamp of the assertion's expiration time
  "name": "Jan Jansen",
  "given_name": "Jan",
  "family_name": "Jansen",
  "email": "jan@gmail.com", // If present, the user's email address
  "email_verified": true,   // true, if Google has verified the email address
  "hd": "example.com",      // If present, the host domain of the user's GSuite email address
                            // If present, a URL to user's profile picture
  "picture": "https://lh3.googleusercontent.com/a-/AOh14GjlTnZKHAeb94A-FmEbwZv7uJD986VOF1mJGb2YYQ",
  "locale": "en_US"         // User's locale, from browser or phone settings
}

بالإضافة إلى التحقّق من توقيع الرمز المميّز، تأكَّد من أنّ التأكيد جهة الإصدار (الحقل iss) هي https://accounts.google.com، بحيث يمكن لشريحة الجمهور (الحقل aud) هو معرّف العميل الذي تم تعيينه، ولم تنتهِ صلاحية الرمز المميّز. (حقل exp).

باستخدام الحقول email وemail_verified وhd، يمكنك تحديد ما إذا كان تستضيف Google عناوين البريد الإلكتروني وموثوقًا بها. في الحالات التي تواجه فيها Google موثوقية المستخدم المعروف حاليًا بأنه صاحب الحساب الشرعي ويمكنك تخطي كلمة المرور أو طرق التحديات الأخرى. بخلاف ذلك، فإن هذه الطرق يمكن استخدامها للتحقّق من الحساب قبل ربطه

الحالات التي تكون فيها Google موثوقة:

  • السمة email هي اللاحقة @gmail.com، وهذا حساب Gmail.
  • email_verified صحيح وتم ضبط hd، هذا حساب G Suite.

يمكن للمستخدمين التسجيل للحصول على حسابات Google بدون استخدام Gmail أو G Suite. فعندما لا يحتوي email على اللاحقة @gmail.com وhd غير موجود في Google موثوقة وكلمة المرور أو طرق التحقق الأخرى للتحقق المستخدم. يمكن أن يكون email_verified صحيحًا أيضًا لأن Google تحققت في البداية من صحة المستخدم عند إنشاء حساب Google، ولكن ملكية الجهة الخارجية ربما تغير حساب بريدك الإلكتروني منذ ذلك الحين.

Validate user information and create new account

Check whether either of the following conditions are true:

  • The Google Account ID, found in the assertion's sub field, is in your user database.
  • The email address in the assertion matches a user in your user database.

If either condition is true, prompt the user to link their existing account with their Google Account. To do so, respond to the request with an HTTP 401 error that specifies error=linking_error and gives the user's email address as the login_hint. The following is a sample response:

HTTP/1.1 401 Unauthorized
Content-Type: application/json;charset=UTF-8

{
  "error":"linking_error",
  "login_hint":"foo@bar.com"
}

When Google receives a 401 error response with linking_error, Google sends the user to your authorization endpoint with login_hint as a parameter. The user completes account linking using the OAuth linking flow in their browser.

If neither condition is true, create a new user account with the information provided in the JWT. New accounts don't typically have a password set. It's recommended that you add Google Sign-In to other platforms to enable users to log in with Google across the surfaces of your application. Alternatively, you can email the user a link that starts your password recovery flow to allow the user to set a password to sign in on other platforms.

When the creation is completed, issue an access token and return the values in a JSON object in the body of your HTTPS response, like in the following example:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",
  "refresh_token": "REFRESH_TOKEN",
  "expires_in": SECONDS_TO_EXPIRATION
}

الحصول على معرّف عميل Google API

سيُطلب منك تقديم معرّف عميل Google API أثناء عملية تسجيل ميزة "ربط الحساب".

للحصول على معرِّف عميل واجهة برمجة التطبيقات باستخدام المشروع الذي أنشأته أثناء إكمال خطوات ربط OAuth. لإجراء ذلك، يُرجى إكمال الخطوات التالية:

  1. أنشئ مشروعًا على Google APIs أو اختَره.

    إذا لم يكن مشروعك يتضمّن معرّف عميل لنوع تطبيق الويب، انقر على إنشاء عميل لإنشاء معرّف. احرص على تضمين نطاق موقعك الإلكتروني في مربّع مصادر JavaScript المسموح بها. عند إجراء اختبارات محلية أو تطوير، يجب إضافة كل من http://localhost و http://localhost:<port_number> إلى حقل مصادر JavaScript المعتمَدة.

التحقّق من صحة عملية التنفيذ

您可以使用 OAuth 2.0 Playground 工具验证您的实现。

在该工具中,执行以下步骤:

  1. 点击配置 以打开 OAuth 2.0 配置窗口。
  2. OAuth flow 字段中,选择 Client-side(客户端)。
  3. OAuth 端点字段中,选择自定义
  4. 在相应字段中指定您的 OAuth 2.0 端点和您分配给 Google 的客户端 ID。
  5. 第 1 步部分,不要选择任何 Google 范围。请将此字段留空或输入对服务器有效的范围(如果您不使用 OAuth 范围,则可以输入任意字符串)。完成后,点击授权 API
  6. Step 2Step 3 部分中,完成 OAuth 2.0 流程,并验证每个步骤是否按预期运行。

您可以使用 Google 账号关联演示版工具验证您的实现。

在该工具中,执行以下步骤:

  1. 点击使用 Google 账号登录按钮。
  2. 选择您要关联的账号。
  3. 输入服务 ID。
  4. (可选)输入您要请求访问权限的一个或多个范围。
  5. 点击开始演示
  6. 当系统提示时,请确认您同意或拒绝关联请求。
  7. 确认您已被重定向到您的平台。