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

نظرة عامة

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

لإجراء ربط الحساب باستخدام OAuth وتسجيل الدخول بحساب Google، يُرجى اتّباع الخطوات العامة التالية:

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

الشكل 1. ربط الحسابات على هاتف المستخدم من خلال الربط السلس

متطلبات الربط السلس

  • نفِّذ تدفق ربط OAuth الأساسي. يجب أن تتوافق خدمتك مع نقاط نهاية التفويض والتبادل المميز المتوافقة مع OAuth 2.0.
  • يجب أن تتوافق نقطة نهاية تبادل الرموز المميّزة مع عمليات تأكيد JSON Web Token (JWT) وتنفيذ عناصر check وcreate وget.

تنفيذ خادم OAuth

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

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

البحث عن حساب مستخدم حالي (التحقّق من القصد)

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

إذا كان حساب Google المقابل موجودًا في نظام المصادقة الذي تستخدمه، ستستجيب نقطة نهاية تبادل الرموز المميّزة باستخدام account_found=true. وإذا لم يتطابق حساب Google مع مستخدم حالي، ستعرض نقطة نهاية تبادل الرموز المميّزة خطأ HTTP 404 لم يتم العثور على الصفحة في 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 المميّز للويب (JWT) الذي يقدّم تأكيدًا موقّعًا هوية المستخدم على Google. يحتوي JWT على معلومات تتضمن رقم تعريف حساب المستخدم على Google واسمه وعنوان بريده الإلكتروني.
client_id معرِّف العميل الذي تم تخصيصه إلى Google.
client_secret سر العميل الذي حددته لـ Google.

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

  • التحقّق من صحة تأكيد JWT وفك ترميزه
  • تحقق مما إذا كان حساب Google موجودًا في نظام المصادقة.
验证和解码 JWT 断言

您可以使用 适用于您所用语言的 JWT 解码库。使用 Google 的公钥,在 JWKPEM 格式,用于验证 令牌的签名。

解码后,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 字段)是分配给您的客户端 ID,并且令牌未过期 (exp 字段)。

使用 emailemail_verifiedhd 字段,您可以确定 Google 负责托管电子邮件地址,并对其具有权威性。如果 Google 权威性 - 用户当前被认定为合法账号所有者 您可以跳过密码或其他验证方法。否则,这些方法 可用于在关联之前验证账号。

Google 具有权威性的情形:

  • email 的后缀为 @gmail.com,这是一个 Gmail 账号。
  • email_verified 为 true 且 hd 已设置,这是 G Suite 账号。

用户无需使用 Gmail 或 G Suite 即可注册 Google 账号。时间 email 不包含 @gmail.com 后缀,且 hd 不存在 Google 不 建议使用权威凭据和密码或其他验证方法进行验证 用户。email_verified 可能为 true,因为 Google 最初验证了 创建 Google 账号后,该用户会获得第三方的所有权, 后,电子邮件账号可能已更改。

تحقق مما إذا كان حساب Google موجودًا في نظام المصادقة.

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

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

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

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

{
  "account_found":"true",
}

إذا لم يتطابق رقم تعريف حساب Google أو عنوان البريد الإلكتروني المحدّد في التقييم مع مستخدم في قاعدة البيانات، لم يشترك المستخدم بعد. في هذه الحالة، تحتاج نقطة نهاية تبادل الرموز المميزة إلى الرد مع تضمين خطأ HTTP 404 الذي يحدد "account_found": "false"، كما هو موضح في المثال التالي:

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

{
  "account_found":"false",
}

处理自动链接(获取 intent)

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

如果您的身份验证系统中已存在相应的 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 Web 令牌 (JWT),用于提供 Google 用户身份的签名断言。JWT 包含用户的 Google 帐号 ID、姓名和电子邮件地址等信息。
scope 可选:您已将 Google 配置为向用户请求的任何范围。
client_id 您分配给 Google 的客户端 ID。
client_secret 您分配给 Google 的客户端密钥。

为了响应 get intent 请求,您的令牌交换端点必须执行以下步骤:

  • 验证并解码 JWT 断言。
  • 检查您的身份验证系统中是否已存在该 Google 帐号。
验证和解码 JWT 断言

您可以使用 适用于您所用语言的 JWT 解码库。使用 Google 的公钥,在 JWKPEM 格式,用于验证 令牌的签名。

解码后,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 字段)是分配给您的客户端 ID,并且令牌未过期 (exp 字段)。

使用 emailemail_verifiedhd 字段,您可以确定 Google 负责托管电子邮件地址,并对其具有权威性。如果 Google 权威性 - 用户当前被认定为合法账号所有者 您可以跳过密码或其他验证方法。否则,这些方法 可用于在关联之前验证账号。

Google 具有权威性的情形:

  • email 的后缀为 @gmail.com,这是一个 Gmail 账号。
  • email_verified 为 true 且 hd 已设置,这是 G Suite 账号。

用户无需使用 Gmail 或 G Suite 即可注册 Google 账号。时间 email 不包含 @gmail.com 后缀,且 hd 不存在 Google 不 建议使用权威凭据和密码或其他验证方法进行验证 用户。email_verified 可能为 true,因为 Google 最初验证了 创建 Google 账号后,该用户会获得第三方的所有权, 后,电子邮件账号可能已更改。

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

检查是否满足以下任一条件:

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

如果找到了用户的帐号,请发出访问令牌,并在 HTTPS 响应的正文中以 JSON 对象形式返回值,如以下示例所示:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

在某些情况下,基于 ID 令牌的帐号关联可能会为用户失败。如果出现任何此类情况,您的令牌交换端点都需要使用返回 error=linking_error 的 HTTP 401 错误进行响应,如以下示例所示:

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

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

Google 收到包含 linking_error 的 401 错误响应后,会将用户作为授权参数 login_hint 发送到您的授权端点。用户在浏览器中使用 OAuth 关联流程完成帐号关联。

通过 Google 登录功能创建帐号(创建 intent)

当用户需要在您的服务上创建帐号时,Google 会向您的令牌交换端点发出请求,并指定 intent=create

请求的格式如下:

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

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

令牌端点参数
intent 对于这些请求,此参数的值为 create
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 的客户端密钥。

assertion 参数中的 JWT 包含用户的 Google 帐号 ID、名称和电子邮件地址,您可以使用这些信息在服务中创建新帐号。

为了响应 create intent 请求,您的令牌交换端点必须执行以下步骤:

  • 验证并解码 JWT 断言。
  • 验证用户信息并创建新帐号。
验证和解码 JWT 断言

您可以使用 适用于您所用语言的 JWT 解码库。使用 Google 的公钥,在 JWKPEM 格式,用于验证 令牌的签名。

解码后,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 字段)是分配给您的客户端 ID,并且令牌未过期 (exp 字段)。

使用 emailemail_verifiedhd 字段,您可以确定 Google 负责托管电子邮件地址,并对其具有权威性。如果 Google 权威性 - 用户当前被认定为合法账号所有者 您可以跳过密码或其他验证方法。否则,这些方法 可用于在关联之前验证账号。

Google 具有权威性的情形:

  • email 的后缀为 @gmail.com,这是一个 Gmail 账号。
  • email_verified 为 true 且 hd 已设置,这是 G Suite 账号。

用户无需使用 Gmail 或 G Suite 即可注册 Google 账号。时间 email 不包含 @gmail.com 后缀,且 hd 不存在 Google 不 建议使用权威凭据和密码或其他验证方法进行验证 用户。email_verified 可能为 true,因为 Google 最初验证了 创建 Google 账号后,该用户会获得第三方的所有权, 后,电子邮件账号可能已更改。

验证用户信息并创建新帐号

检查是否满足以下任一条件:

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

如果任一条件为 true,请提示用户将其现有帐号与其 Google 帐号相关联。为此,请对请求进行响应,并提供指定 error=linking_error 并将用户的电子邮件地址作为 login_hint 的 HTTP 401 错误。以下是一个示例响应:

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

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

Google 收到包含 linking_error 的 401 错误响应后,会将用户作为授权参数 login_hint 发送到您的授权端点。用户在浏览器中使用 OAuth 关联流程完成帐号关联。

如果两个条件都不满足,请使用 JWT 中提供的信息创建新的用户帐号。新帐号通常不会设置密码。建议您将 Google 登录功能添加到其他平台,以便用户能够在应用界面使用 Google 帐号登录。或者,您也可以通过电子邮件向用户发送一个启动密码恢复流程的链接,以便用户设置密码以在其他平台上登录。

创建完成后,发出访问令牌 ,并在 HTTPS 响应的正文中以 JSON 对象形式返回值,如以下示例所示:

{
  "token_type": "Bearer",
  "access_token": "ACCESS_TOKEN",

  "expires_in": SECONDS_TO_EXPIRATION
}

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

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

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

  1. افتح صفحة بيانات الاعتماد في وحدة تحكّم Google API.
  2. أنشئ مشروع Google APIs أو اختَره.

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

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

يمكنك التحقق من صحة التطبيق الخاص بك باستخدام ملعب أوث 2.0 الأداة.

في الأداة ، قم بالخطوات التالية:

  1. انقر فوق تكوين لفتح نافذة تكوين أوث 2.0.
  2. في مجال تدفق أوث، اختر من جانب العميل.
  3. في مجال أوث النهايات، حدد مخصص.
  4. حدد نقطة نهاية OAuth 2.0 ومعرف العميل الذي عينته لـ Google في الحقول المقابلة.
  5. في القسم الخطوة 1، لا تحدد أي نطاقات جوجل. بدلاً من ذلك ، اترك هذا الحقل فارغًا أو اكتب نطاقًا صالحًا لخادمك (أو سلسلة عشوائية إذا كنت لا تستخدم نطاقات OAuth). عند الانتهاء من ذلك، انقر فوق تخويل واجهات برمجة التطبيقات.
  6. في الأقسام الخطوة 2 و الخطوة 3، انتقل من خلال تدفق أوث 2.0 والتحقق من أن كل خطوة تعمل على النحو المنشود.

يمكنك التحقق من صحة التطبيق الخاص بك باستخدام حساب Google ربط تجريبي الأداة.

في الأداة ، قم بالخطوات التالية:

  1. انقر على تسجيل الدخول باستخدام زر جوجل.
  2. اختر الحساب الذي ترغب في ربطه.
  3. أدخل معرف الخدمة.
  4. اختياريًا ، أدخل نطاقًا واحدًا أو أكثر ستطلب الوصول إليه.
  5. انقر فوق ابدأ تجريبي.
  6. عند المطالبة ، أكد أنه يمكنك الموافقة ورفض طلب الربط.
  7. تأكد من إعادة توجيهك إلى النظام الأساسي الخاص بك.