نظرة عامة
في 16 شباط (فبراير) 2022، أعلنّا عن خططنا لجعل تفاعلات Google OAuth أكثر أمانًا من خلال استخدام مسارات OAuth أكثر أمانًا. يساعدك هذا الدليل في فهم التغييرات والخطوات اللازمة لنقل البيانات بنجاح من عملية OAuth خارج النطاق (OOB) إلى البدائل المتوافقة.
وهذه الجهود هي إجراء وقائي ضد هجمات التصيّد الاحتيالي وانتحال هوية التطبيقات أثناء التفاعلات مع نقاط نهاية التفويض في بروتوكول OAuth 2.0 من Google.
ما هو المقصود بـ OOB؟
مسار OAuth خارج النطاق (OOB)، الذي يُشار إليه أيضًا باسم خيار النسخ/اللصق اليدوي، هو مسار قديم تم تطويره لتوفير الدعم للعملاء الأصليين الذين لا يملكون معرّف موارد منتظم (URI) لإعادة التوجيه لقبول بيانات الاعتماد بعد موافقة المستخدم على طلب موافقة OAuth. يشكّل مسار OOB خطرًا متعلّقًا بالتصيّد الاحتيالي عن بُعد، ويجب على العملاء نقل بياناتهم إلى طريقة بديلة للحماية من هذه الثغرة الأمنية.سيتم إيقاف مسار "التسجيل خارج النطاق" نهائيًا لجميع أنواع العملاء، مثل تطبيقات الويب و Android وiOS وUniversal Windows Platform (UWP) وتطبيقات Chrome وأجهزة التلفزيون و الأجهزة التي تتضمّن إمكانيات إدخال محدودة وتطبيقات الكمبيوتر المكتبي.
التواريخ الرئيسية للامتثال
- 28 شباط (فبراير) 2022: حظر استخدام OAuth الجديد لمسار "الخروج من التطبيق"
- 5 أيلول (سبتمبر) 2022: قد يتم عرض رسالة تحذير موجّهة للمستخدمين على طلبات OAuth غير المتوافقة.
- 3 تشرين الأول (أكتوبر) 2022: سيتم إيقاف مسار الموافقة خارج نطاق التطبيق نهائيًا لعملاء OAuth الذين تم إنشاؤهم قبل 28 شباط (فبراير) 2022.
- 31 كانون الثاني (يناير) 2023: سيتم حظر جميع العملاء الحاليين (بما في ذلك العملاء المُعفى)
سيتم عرض رسالة خطأ موجّهة للمستخدمين للطلبات غير الممتثلة للمتطلبات. ستُعلم الرسالة المستخدمين بأنّه تم حظر التطبيق مع عرض عنوان البريد الإلكتروني المخصّص للدعم الذي سجّلته في شاشة طلب الموافقة المتعلّقة ببروتوكول OAuth في وحدة تحكّم Google API.
- تحديد ما إذا كنت متأثرًا بالتغيير
- انتقِل إلى بديل أكثر أمانًا إذا كنت متأثرًا.
تحديد ما إذا كنت متأثرًا
لا ينطبق إيقاف هذا الإصدار نهائيًا إلا على التطبيقات العلنية (أي التطبيقات التي تم ضبط حالة نشرها على في مرحلة الإنتاج). سيستمر الإجراء في العمل للتطبيقات التي تحمل حالة الاختبار النشر.
راجِع حالة النشر في OAuth من وانتقِل إلى الخطوة التالية إذا كنت تستخدم عملية الخروج من المنظومة (OOB) في مشروع حالته "قيد الإصدار".
كيفية تحديد ما إذا كان تطبيقك يستخدم مسار الخروج من التطبيق
تحقّق من رمز تطبيقك أو طلب الاتصال بالشبكة الصادر (في حال كان تطبيقك يستخدم مكتبة OAuth) لتحديد ما إذا كان طلب التفويض الذي يقدّمه تطبيقك باستخدام 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
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>
فحص مكالمة الشبكة الصادرة
- تطبيق الويب: فحص نشاط الشبكة على Chrome
- Android: التحقّق من حركة بيانات الشبكة باستخدام "أداة فحص الشبكة"
-
تطبيقات Chrome
- انتقِل إلى صفحة الإضافات في Chrome.
- ضَع علامة في مربّع الاختيار وضع المطوّر في أعلى يسار صفحة الإضافة.
- اختَر الإضافة التي تريد مراقبتها.
- انقر على رابط صفحة الخلفية في القسم فحص المشاهدات في صفحة الإضافة.
- ستظهر نافذة منبثقة لأدوات المطوّرين يمكنك من خلالها تتبُّع حركة بيانات الشبكة في علامة التبويب "الشبكة".
- iOS: تحليل عدد زيارات HTTP باستخدام Instruments
- Universal Windows Platform (UWP): فحص حركة مرور الشبكة في Visual Studio
- تطبيقات الكمبيوتر المكتبي: استخدام أداة لتسجيل بيانات الشبكة متاحة لنظام التشغيل الذي تم تطوير التطبيق له
redirect_uri
تحتوي على أيّ من القيمة التالية:
redirect_uri=urn:ietf:wg:oauth:2.0:oob
redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
redirect_uri=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)
إذا تبيّن لك أنّ تطبيقك يستخدم عملية تسجيل الدخول خارج التطبيق مع نوع ملف تعريف مستخدم OAuth لنظامَي التشغيل Android أو iOS ، عليك نقل البيانات لاستخدام حِزم تطوير البرامج (SDK) المُقترَحة (Android، iOS).
تسهِّل حِزم تطوير البرامج (SDK) الوصول إلى Google APIs وتعالج جميع طلبات برمجة التطبيقات المرسَلة إلى نقاط نهاية التفويض في OAuth 2.0 من Google.
تقدّم روابط المستندات أدناه معلومات عن كيفية استخدام حِزم تطوير البرامج (SDK) المقترَحة للوصول إلى واجهات برمجة تطبيقات Google بدون استخدام معرّف موارد منتظم (URI) لإعادة التوجيه خارج النطاق.
الوصول إلى واجهات برمجة تطبيقات Google على Android
الوصول من جهة العميل
يوضّح المثال التالي كيفية الوصول إلى Google APIs من جانب العميل على Android باستخدام مكتبة Google Identity Services المُقترَحة لنظام التشغيل Android.
ListrequestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA); AuthorizationRequest authorizationRequest = AuthorizationRequest.builder().setRequestedScopes(requestedScopes).build(); Identity.getAuthorizationClient(activity) .authorize(authorizationRequest) .addOnSuccessListener( authorizationResult -> { if (authorizationResult.hasResolution()) { // Access needs to be granted by the user PendingIntent pendingIntent = authorizationResult.getPendingIntent(); try { startIntentSenderForResult(pendingIntent.getIntentSender(), REQUEST_AUTHORIZE, null, 0, 0, 0, null); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage()); } } else { // Access already granted, continue with user action saveToDriveAppFolder(authorizationResult); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
نقْل القيمة authorizationResult
إلى الطريقة المحدّدة لحفظ المحتوى في مجلد Drive الخاص بالمستخدم. يحتوي authorizationResult
على الطريقة
getAccessToken()
التي تُعرِض رمز الدخول.
الوصول من جهة الخادم (بلا إنترنت)
يوضّح المثال التالي كيفية الوصول إلى Google APIs من جهة الخادم على Android.ListrequestedScopes = Arrays.asList(DriveScopes.DRIVE_APPDATA); AuthorizationRequest authorizationRequest = AuthorizationRequest.builder() .requestOfflineAccess(webClientId) .setRequestedScopes(requestedScopes) .build(); Identity.getAuthorizationClient(activity) .authorize(authorizationRequest) .addOnSuccessListener( authorizationResult -> { if (authorizationResult.hasResolution()) { // Access needs to be granted by the user PendingIntent pendingIntent = authorizationResult.getPendingIntent(); try { startIntentSenderForResult(pendingIntent.getIntentSender(), REQUEST_AUTHORIZE, null, 0, 0, 0, null); } catch (IntentSender.SendIntentException e) { Log.e(TAG, "Couldn't start Authorization UI: " + e.getLocalizedMessage()); } } else { String authCode = authorizationResult.getServerAuthCode(); } }) .addOnFailureListener(e -> Log.e(TAG, "Failed to authorize", e));
يحتوي authorizationResult
على
getServerAuthCode()
التي تُعرِض رمز التفويض الذي يمكنك إرساله إلى
getServerAuthCode()
للحصول على رمزَي الوصول وإعادة التحميل.
الوصول إلى واجهات برمجة تطبيقات Google في تطبيق 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 للغة Objective-C لواجهة برمجة التطبيقات REST.
راجِع دليل الوصول من جهة العميل للتعرّف على كيفية الوصول إلى واجهات برمجة تطبيقات Google من جهة العميل. حول كيفية الوصول إلى 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 من جهة الخادم.
برنامج Chrome App Client
إذا تبيّن لك أنّ تطبيقك يستخدم عملية "خارج النطاق" على العميل لتطبيق Chrome، عليك نقل البيانات لاستخدام Chrome Identity API.
يوضّح المثال أدناه كيفية الحصول على جميع جهات اتصال المستخدم بدون استخدام عنوان URL لإعادة التوجيه خارج نطاق التطبيق.
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 Identity API للحصول على مزيد من المعلومات حول كيفية الوصول إلى المستخدمين الذين تمّت مصادقتهم والاتّصال بنقط نهاية Google باستخدام Chrome Identity API.
تطبيق الويب
إذا تبيّن لك أنّ تطبيقك يستخدم مسار بروتوكول OAuth خارج نطاق المؤسسة لتطبيق ويب، عليك نقل البيانات لاستخدام إحدى مكتبات عملاء Google API. يمكنك الاطّلاع على مكتبات العميل بلغات برمجة مختلفة هنا.
تسهّل المكتبات الوصول إلى واجهات برمجة تطبيقات Google ومعالجة جميع طلبات البيانات المرسَلة إلى نقاط نهاية Google.
الوصول من جهة الخادم (بلا إنترنت)
- يمكنك إعداد خادم وتحديد نقطة نهاية متاحة للجميع (معرّف الموارد المنتظم لإعادة التوجيه) لتلقّي رمز التفويض.
- اضبط معرّف الموارد المنتظم (URI) لإعادة التوجيه في من .
تعرِض المقتطفة أدناه من الرمز البرمجي مثالاً على NodeJS لاستخدام Google Drive API لعرض ملفات المستخدم على Google Drive من جهة الخادم بدون استخدام معرّف موارد منتظم لإعادة التوجيه خارج نطاق التطبيق.
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 من جهة الخادم.
الوصول من جهة العميل
يعرض مقتطف الرمز البرمجي أدناه، بتنسيق 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 من جهة العميل.
برنامج سطح المكتب
إذا تبيّن لك أنّ تطبيقك يستخدم مسار "خارج النطاق" على عميل كمبيوتر مكتبي،
عليك نقل البيانات إلى استخدام
مسار عنوان IP الاستماع إلى صوتك (localhost
أو 127.0.0.1
).