دليل نقل التدفق خارج النطاق (OOB)

نظرة عامة

في 16 شباط (فبراير) 2022، أعلنّا عن خطط لجعل تفاعلات OAuth مع Google أكثر أمانًا باستخدام مسارات OAuth أكثر أمانًا. يساعدك هذا الدليل على فهم التغييرات اللازمة والخطوات اللازمة للانتقال بنجاح من مسار OAuth خارج الإطار (OOB) إلى البدائل المتوافقة.

تهدف هذه الجهود إلى توفير إجراءات حماية ضد التصيّد الاحتيالي وهجمات انتحال هوية التطبيقات أثناء التفاعل مع نقاط نهاية تفويض OAuth 2.0 من Google.

ما هو OOB؟

إنّ بروتوكول OAuth خارج الإطار (OOB)، والمشار إليه أيضًا بخيار النسخ/اللصق اليدوي، هو مسار قديم تم تطويره لدعم العملاء الأصليين الذين لا يملكون عنوان URL لإعادة التوجيه من أجل قبول بيانات الاعتماد بعد موافقة المستخدم على طلب الموافقة على OAuth. يشكّل تدفق OOB خطرًا من خلال التصيّد الاحتيالي عن بُعد ويجب على العملاء الانتقال إلى طريقة بديلة للحماية من هذه الثغرة الأمنية.

يتم إيقاف مسار OOB نهائيًا في جميع أنواع العملاء، مثل تطبيقات الويب وAndroid وiOS وUniversal Windows Platform (UWP) وتطبيقات Chrome وأجهزة التلفزيون والأجهزة ذات الإدخال المحدود والتطبيقات المتوافقة مع أجهزة الكمبيوتر المكتبي.

تواريخ الامتثال الرئيسية

  • 28 شباط (فبراير) 2022 - تم حظر استخدام OAuth الجديد في مسار OOB
  • 5 أيلول (سبتمبر) 2022: قد يتم عرض رسالة تحذيرية للمستخدمين بشأن طلبات OAuth غير المتوافقة مع السياسة.
  • 3 تشرين الأول (أكتوبر) 2022: تم إيقاف مسار OOB لعملاء OAuth الذين تم إنشاؤهم قبل 28 شباط (فبراير) 2022.
  • 31 كانون الثاني (يناير) 2023 - تم حظر جميع البرامج الحالية (بما في ذلك العملاء المستثناون)

سيتم عرض رسالة خطأ تظهر للمستخدمين للطلبات غير المتوافقة. سترسل الرسالة إلى المستخدمين معلومات تفيد بأنّ التطبيق تم حظره مع عرض رسالة الدعم الإلكترونية التي سجّلتها في شاشة طلب الموافقة على OAuth ضمن وحدة تحكُّم Google API.

هناك خطوتان أساسيتان لإكمال عملية نقل البيانات:
  1. يُرجى تحديد ما إذا كانت هذه المشكلة تؤثر في حسابك.
  2. ننصحك بنقل بياناتك إلى بديل أكثر أمانًا في حال كنت متأثرًا بالمشكلة.

تحديد ما إذا كنت متأثرًا بالمشكلة

لا ينطبق هذا الإيقاف النهائي إلّا على تطبيقات الإنتاج (أي التطبيقات التي تم ضبط حالة النشر فيها على في مرحلة الإنتاج. وسيستمرّ المسار في العمل مع التطبيقات التي تحمل حالة نشر الاختبار.

راجِع حالة النشر في بروتوكول OAuth Consent Screen pageمن Google API Console وانتقِل إلى الخطوة التالية إذا كنت تستخدم مسار OOB في مشروع بحالة النشر "قيد الإنتاج".

كيفية تحديد ما إذا كان تطبيقك يستخدم مسار OOB

افحص رمز تطبيقك أو مكالمة الشبكة الصادرة (في حال كان تطبيقك يستخدم مكتبة OAuth) لتحديد ما إذا كان طلب تفويض Google OAuth الذي ينشئه تطبيقك يستخدم قيمة معرّف موارد منتظم (URI) لإعادة توجيه OOB.

فحص رمز تطبيقك

راجِع قسم رمز التطبيق الذي تُجري فيه طلبًا إلى نقاط نهاية تفويض Google OAuth، ثم حدِّد ما إذا كانت المعلَمة redirect_uri تحتوي على أي من القيم التالية:
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
سيبدو نموذج طلب مسار إعادة التوجيه OOB على النحو التالي:
https://accounts.google.com/o/oauth2/v2/auth?
response_type=code&
scope=<SCOPES>&
state=<STATE>&
redirect_uri=urn:ietf:wg:oauth:2.0:oob&
client_id=<CLIENT_ID>

فحص مكالمة الشبكة الصادرة

ستختلف طريقة فحص استدعاءات الشبكة بناءً على نوع برنامج التطبيق.
أثناء فحص طلبات الشبكة، ابحث عن الطلبات المُرسَلة إلى نقاط نهاية تفويض OAuth في Google وحدِّد ما إذا كانت المعلَمة redirect_uri تحتوي على أي من القيم التالية:
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
سيظهر نموذج طلب مسار إعادة التوجيه OOB على النحو التالي:
https://accounts.google.com/o/oauth2/v2/auth?
response_type=code&
scope=<SCOPES>&
state=<STATE>&
redirect_uri=urn:ietf:wg:oauth:2.0:oob&
client_id=<CLIENT_ID>

نقل البيانات إلى بديل آمن

برامج الأجهزة الجوّالة (Android / iOS)

إذا تبيّن لك أنّ تطبيقك يستخدم مسار OOB مع نوع عميل OAuth لنظام التشغيل Android أو iOS، عليك نقل البيانات إلى استخدام حِزم تطوير البرامج (SDK) للأجهزة الجوّالة لتسجيل الدخول بحساب Google (على Android وiOS).

تسهِّل حزمة تطوير البرامج (SDK) الوصول إلى Google APIs وتعالج جميع الطلبات إلى نقاط نهاية تفويض OAuth 2.0 من Google.

توفّر روابط المستندات أدناه معلومات عن كيفية استخدام حِزم تطوير البرامج (SDK) لتسجيل الدخول بحساب Google للوصول إلى Google APIs بدون استخدام معرّف موارد منتظم (URI) لإعادة توجيه OOB.

الوصول إلى Google APIs على نظام التشغيل Android

الوصول من جهة الخادم (بلا اتصال بالإنترنت)
يوضِّح المثال أدناه كيفية الوصول إلى Google APIs على جانب الخادم على Android.
Task<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data);
try {
  GoogleSignInAccount account = task.getResult(ApiException.class);
  
  // request a one-time authorization code that your server exchanges for an
  // access token and sometimes refresh token
  String authCode = account.getServerAuthCode();
  
  // Show signed-in UI
  updateUI(account);

  // TODO(developer): send code to server and exchange for access/refresh/ID tokens
} catch (ApiException e) {
  Log.w(TAG, "Sign-in failed", e);
  updateUI(null);
}

راجِع دليل الوصول من جهة الخادم للتعرّف على كيفية الوصول إلى Google APIs من جهة الخادم.

الوصول إلى Google APIs في تطبيق iOS

الوصول من جهة العميل

يوضح المثال أدناه كيفية الوصول إلى Google APIs من جهة العميل على نظام iOS.

user.authentication.do { authentication, error in
  guard error == nil else { return }
  guard let authentication = authentication else { return }
  
  // Get the access token to attach it to a REST or gRPC request.
  let accessToken = authentication.accessToken
  
  // Or, get an object that conforms to GTMFetcherAuthorizationProtocol for
  // use with GTMAppAuth and the Google APIs client library.
  let authorizer = authentication.fetcherAuthorizer()
}

استخدِم رمز الدخول لطلب بيانات واجهة برمجة التطبيقات، إما عن طريق تضمين رمز الدخول في عنوان طلب REST أو gRPC (Authorization: Bearer ACCESS_TOKEN)، أو من خلال استخدام إذن الجلب (GTMFetcherAuthorizationProtocol) مع مكتبة عملاء Google APIs للأهداف REST.

راجِع دليل الوصول من جهة العميل لمعرفة كيفية الوصول إلى Google APIs من جهة العميل. حول كيفية الوصول إلى Google APIs من جهة العميل

الوصول من جهة الخادم (بلا اتصال بالإنترنت)
يوضح المثال أدناه كيفية الوصول إلى Google APIs من جهة الخادم لدعم برنامج iOS.
GIDSignIn.sharedInstance.signIn(with: signInConfig, presenting: self) { user, error in
  guard error == nil else { return }
  guard let user = user else { return }
  
  // request a one-time authorization code that your server exchanges for
  // an access token and refresh token
  let authCode = user.serverAuthCode
}

راجِع دليل الوصول من جهة الخادم للتعرّف على كيفية الوصول إلى Google APIs من جهة الخادم.

برنامج تطبيق Chrome

إذا تبيّن لك أنّ تطبيقك يستخدم مسار OOB على برنامج تطبيق Chrome، عليك الانتقال إلى استخدام Chrome Identity API.

يوضّح المثال أدناه كيفية الحصول على جميع جهات اتصال المستخدمين بدون استخدام معرّف الموارد المنتظم (URI) لإعادة توجيه OOB.

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {

  
  // retrieve access token
  chrome.identity.getAuthToken({interactive: true}, function(token) {
  
  // ..........


  // the example below shows how to use a retrieved access token with an appropriate scope
  // to call the Google People API contactGroups.get endpoint

  fetch(
    'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=API_KEY',
    init)
    .then((response) => response.json())
    .then(function(data) {
      console.log(data)
    });
   });
 });
};

يمكنك مراجعة دليل واجهة برمجة تطبيقات الهوية لـ Chrome للحصول على مزيد من المعلومات حول طريقة الوصول إلى المصادقة على المستخدمين والاتصال بنقاط نهاية Google باستخدام Chrome Identity API.

تطبيق الويب

إذا تبيّن لك أنّ تطبيقك يستخدم مسار OOB لتطبيق ويب، عليك الانتقال إلى استخدام إحدى مكتبات عملاء Google API. يمكنك الاطّلاع هنا على مكتبات العملاء المخصّصة للغات البرمجة المختلفة.

تسهّل المكتبات الوصول إلى Google APIs وتعالج جميع الطلبات إلى نقاط النهاية من Google.

الوصول من جهة الخادم (بلا اتصال بالإنترنت)
يتطلب وضع الوصول من جهة الخادم (بلا اتصال بالإنترنت) ما يلي:

يعرض مقتطف الرمز أدناه مثالاً على NodeJS لاستخدام Google Drive API لإدراج ملفات Google Drive للمستخدم على جهة الخادم بدون استخدام معرّف موارد منتظم (URI) لإعادة توجيه OOB.

async function main() {
  const server = http.createServer(async function (req, res) {

  if (req.url.startsWith('/oauth2callback')) {
    let q = url.parse(req.url, true).query;

    if (q.error) {
      console.log('Error:' + q.error);
    } else {
      
      // Get access and refresh tokens (if access_type is offline)
      let { tokens } = await oauth2Client.getToken(q.code);
      oauth2Client.setCredentials(tokens);

      // Example of using Google Drive API to list filenames in user's Drive.
      const drive = google.drive('v3');
      drive.files.list({
        auth: oauth2Client,
        pageSize: 10,
        fields: 'nextPageToken, files(id, name)',
      }, (err1, res1) => {
        // TODO(developer): Handle response / error.
      });
    }
  }
}

راجِع دليل تطبيق الويب من جهة الخادم حول كيفية الوصول إلى Google APIs من جهة الخادم.

الوصول من جهة العميل

يعرض مقتطف الرمز أدناه، في JavaScript، مثالاً على استخدام Google API للوصول إلى أحداث تقويم المستخدم من جهة العميل.


// initTokenClient() initializes a new token client with your
// web app's client ID and the scope you need access to

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  
  // callback function to handle the token response
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) { 
      gapi.client.setApiKey('YOUR_API_KEY');
      gapi.client.load('calendar', 'v3', listUpcomingEvents);
    }
  },
});

function listUpcomingEvents() {
  gapi.client.calendar.events.list(...);
}

راجِع دليل تطبيق الويب من جهة العميل للتعرّف على كيفية الوصول إلى Google APIs من جهة العميل.

عميل سطح المكتب

إذا تبيّن لك أنّ تطبيقك يستخدم مسار OOB على برنامج أجهزة الكمبيوتر المكتبي، عليك الانتقال إلى استخدام مسار عنوان IP للاسترجاع (localhost أو 127.0.0.1).