راهنمای انتقال جریان آدرس IP Loopback

نمای کلی

در ۱۶ فوریه ۲۰۲۲، ما برنامه‌هایی را برای ایمن‌تر کردن تعاملات Google OAuth با استفاده از جریان‌های امن‌تر OAuth اعلام کردیم . این راهنما به شما کمک می‌کند تا تغییرات و مراحل لازم برای مهاجرت موفقیت‌آمیز از جریان آدرس IP loopback به جایگزین‌های پشتیبانی‌شده را درک کنید.

این تلاش، یک اقدام حفاظتی در برابر حملات فیشینگ و جعل هویت برنامه در حین تعامل با نقاط پایانی احراز هویت OAuth 2.0 گوگل است.

جریان آدرس IP حلقه برگشتی چیست؟

جریان آدرس IP حلقه‌پشتیبانی از استفاده از یک آدرس IP حلقه‌پشتی یا localhost به عنوان جزء میزبان URI تغییر مسیر پشتیبانی می‌کند که در آن اعتبارنامه‌ها پس از تأیید درخواست رضایت OAuth توسط کاربر، به آنجا ارسال می‌شوند. این جریان در برابر حملات مرد میانی آسیب‌پذیر است که در آن یک برنامه مخرب، با دسترسی به همان رابط حلقه‌پشتی در برخی از سیستم عامل‌ها، ممکن است پاسخ سرور مجوز به URI تغییر مسیر داده شده را رهگیری کرده و به کد مجوز دسترسی پیدا کند.

جریان آدرس IP حلقه‌پشتیبان برای انواع کلاینت‌های OAuth بومی iOS، اندروید و Chrome منسوخ شده است، اما همچنان در برنامه‌های دسکتاپ پشتیبانی خواهد شد.

تاریخ‌های کلیدی انطباق

  • ۱۴ مارس ۲۰۲۲ - کلاینت‌های جدید OAuth از استفاده از جریان آدرس IP Loopback منع شدند
  • ۱ آگوست ۲۰۲۲ - ممکن است یک پیام هشدار برای کاربر در درخواست‌های OAuth ناسازگار نمایش داده شود.
  • ۳۱ آگوست ۲۰۲۲ - جریان آدرس IP حلقه‌پشتی برای کلاینت‌های OAuth بومی اندروید، برنامه کروم و iOS که قبل از ۱۴ مارس ۲۰۲۲ ایجاد شده‌اند، مسدود شده است.
  • ۲۱ اکتبر ۲۰۲۲ - همه کلاینت‌های موجود مسدود شدند (از جمله کلاینت‌های معاف)

یک پیام خطا برای درخواست‌های نامطابق با قوانین نمایش داده می‌شود. این پیام به کاربران اطلاع می‌دهد که برنامه مسدود شده است و همزمان ایمیل پشتیبانی که در صفحه رضایت OAuth در کنسول API گوگل ثبت کرده‌اید را نمایش می‌دهد.

برای طی کردن فرآیند مهاجرت، دو مرحله اصلی وجود دارد که باید انجام شوند:
  1. مشخص کنید که آیا تحت تأثیر قرار گرفته‌اید یا خیر.
  2. اگر تحت تأثیر قرار گرفتید، به یک جایگزین پشتیبانی‌شده مهاجرت کنید.

مشخص کنید که آیا تحت تأثیر قرار گرفته‌اید یا خیر

نوع شناسه کلاینت OAuth خود را بررسی کنید

به صفحه کلاینت‌ها در کنسول گوگل کلود بروید و نوع شناسه کلاینت OAuth خود را در بخش شناسه‌های کلاینت OAuth 2.0 مشاهده کنید. این می‌تواند هر یک از موارد زیر باشد: برنامه وب ، اندروید ، iOS ، پلتفرم جهانی ویندوز (UWP) ، برنامه کروم ، تلویزیون‌ها و دستگاه‌های ورودی محدود ، برنامه دسکتاپ .

اگر نوع کلاینت شما اندروید، اپلیکیشن کروم یا iOS است و از جریان آدرس IP حلقه‌ای استفاده می‌کنید، به مرحله بعدی بروید.

اگر از جریان آدرس IP حلقه‌ای در یک کلاینت OAuth برنامه دسکتاپ استفاده می‌کنید، نیازی به انجام کاری در رابطه با این منسوخ‌سازی ندارید، زیرا استفاده از آن نوع کلاینت OAuth همچنان پشتیبانی خواهد شد.

چگونه تشخیص دهیم که آیا برنامه شما از جریان آدرس IP loopback استفاده می‌کند یا خیر

کد برنامه یا فراخوانی شبکه خروجی (در صورتی که برنامه شما از کتابخانه OAuth استفاده می‌کند) را بررسی کنید تا مشخص شود که آیا درخواست مجوز Google OAuth که برنامه شما ارسال می‌کند، از مقادیر URI ریدایرکت loopback استفاده می‌کند یا خیر.

کد برنامه خود را بررسی کنید

بخشی از کد برنامه خود را که در آن به نقاط پایانی مجوز Google OAuth فراخوانی انجام می‌دهید، بررسی کنید و بررسی کنید که آیا پارامتر redirect_uri دارای مقادیر زیر است یا خیر:
  • redirect_uri=http://127.0.0.1: <port> مثال: redirect_uri=http://127.0.0.1: 3000
  • redirect_uri=http://[::1]: <port> مثال: redirect_uri=http://[::1]: 3000
  • redirect_uri=http://localhost: <port> مثال: redirect_uri=http://localhost: 3000
یک نمونه درخواست جریان تغییر مسیر آدرس IP loopback مانند نمونه زیر خواهد بود:
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

بررسی تماس‌های خروجی شبکه

روش بررسی فراخوانی‌های شبکه بسته به نوع کلاینت برنامه شما متفاوت خواهد بود.
هنگام بررسی فراخوانی‌های شبکه، درخواست‌های ارسال شده به نقاط پایانی مجوز Google OAuth را جستجو کنید و بررسی کنید که آیا پارامتر redirect_uri دارای مقادیر زیر است یا خیر:
  • redirect_uri=http://127.0.0.1: <port> مثال: redirect_uri=http://127.0.0.1: 3000
  • redirect_uri=http://[::1]: <port> مثال: redirect_uri=http://[::1]: 3000
  • redirect_uri=http://localhost: <port> مثال: redirect_uri=http://localhost: 3000
یک نمونه درخواست جریان تغییر مسیر آدرس IP loopback مانند نمونه زیر خواهد بود:
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

به یک جایگزین پشتیبانی‌شده مهاجرت کنید

کلاینت‌های موبایل (اندروید / iOS)

اگر تشخیص دادید که برنامه شما از جریان آدرس IP حلقه‌ای با نوع کلاینت OAuth اندروید یا iOS استفاده می‌کند، باید به استفاده از SDK های توصیه شده ( اندروید ، iOS ) مهاجرت کنید.

این SDK دسترسی به APIهای گوگل را آسان می‌کند و تمام فراخوانی‌ها به نقاط پایانی احراز هویت OAuth 2.0 گوگل را مدیریت می‌کند.

لینک‌های مستندات زیر اطلاعاتی در مورد نحوه استفاده از SDK های توصیه شده برای دسترسی به API های گوگل بدون استفاده از آدرس IP loopback و ریدایرکت URI ارائه می‌دهند.

دسترسی به API های گوگل در اندروید

دسترسی سمت کلاینت

مثال زیر نحوه دسترسی به API های گوگل در سمت کلاینت در اندروید را با استفاده از کتابخانه اندروید Google Identity Services که توصیه می‌شود، نشان می‌دهد.

  List requestedScopes = 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 به متد تعریف شده خود ارسال کنید تا محتوا در پوشه درایو کاربر ذخیره شود. authorizationResult دارای متد getAccessToken() است که توکن دسترسی را برمی‌گرداند.

دسترسی سمت سرور (آفلاین)
مثال زیر نحوه دسترسی به API های گوگل در سمت سرور در اندروید را نشان می‌دهد.
  List requestedScopes = 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() است که کد مجوز را برمی‌گرداند و شما می‌توانید آن را به backend خود ارسال کنید تا یک توکن دسترسی و refresh دریافت کنید.

دسترسی به API های گوگل در یک برنامه iOS

دسترسی سمت کلاینت

مثال زیر نحوه دسترسی به API های گوگل در سمت کلاینت در 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()
}

از توکن دسترسی برای فراخوانی API استفاده کنید، یا با قرار دادن توکن دسترسی در هدر درخواست REST یا gRPC ( Authorization: Bearer ACCESS_TOKEN ) یا با استفاده از مجوز دهنده‌ی واکشی ( GTMFetcherAuthorizationProtocol ) با کتابخانه‌ی کلاینت Google APIs برای Objective-C برای REST .

راهنمای دسترسی سمت کلاینت را در مورد نحوه دسترسی به APIهای گوگل در سمت کلاینت مرور کنید.

دسترسی از سمت سرور (آفلاین)
مثال زیر نحوه دسترسی به API های گوگل در سمت سرور برای پشتیبانی از یک کلاینت 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
}

راهنمای دسترسی سمت سرور را در مورد نحوه دسترسی به API های گوگل از سمت سرور مرور کنید.

کلاینت برنامه کروم

اگر تشخیص دادید که برنامه شما از جریان آدرس IP حلقه‌ای در کلاینت برنامه Chrome استفاده می‌کند، باید به استفاده از API هویت Chrome مهاجرت کنید.

مثال زیر نحوه دریافت تمام مخاطبین کاربر را بدون استفاده از آدرس IP loopback ریدایرکت URI نشان می‌دهد.

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)
    });
   });
 });
};

برای اطلاعات بیشتر در مورد نحوه دسترسی به احراز هویت کاربران و فراخوانی نقاط انتهایی گوگل با استفاده از API هویت کروم، راهنمای API هویت کروم را مرور کنید.