Hướng dẫn di chuyển luồng địa chỉ IP Loopback

Tổng quan

Vào ngày 16 tháng 2 năm 2022, chúng tôi đã thông báo về kế hoạch tăng cường bảo mật cho các hoạt động tương tác bằng OAuth của Google bằng cách sử dụng các quy trình OAuth an toàn hơn. Hướng dẫn này giúp bạn hiểu những thay đổi và bước cần thiết để di chuyển thành công từ luồng địa chỉ IP loopback sang các giải pháp thay thế được hỗ trợ.

Đây là biện pháp bảo vệ chống lại các cuộc tấn công giả mạo và lừa đảo ứng dụng trong quá trình tương tác với các điểm cuối uỷ quyền OAuth 2.0 của Google.

Luồng địa chỉ IP Loopback là gì?

Luồng địa chỉ IP vòng lặp hỗ trợ việc sử dụng địa chỉ IP vòng lặp hoặc localhost làm thành phần lưu trữ của URI chuyển hướng nơi thông tin xác thực được gửi đến sau khi người dùng phê duyệt yêu cầu đồng ý OAuth. Quy trình này dễ bị tấn công xen giữa, trong đó một ứng dụng độc hại truy cập vào cùng một giao diện vòng lặp trên một số hệ điều hành có thể chặn phản hồi từ máy chủ uỷ quyền đến URI chuyển hướng đã cho và có quyền truy cập vào mã uỷ quyền.

Quy trình địa chỉ IP loopback không còn được dùng cho các loại ứng dụng OAuth gốc trên iOS, Android và Chrome, nhưng sẽ tiếp tục được hỗ trợ trên các ứng dụng dành cho máy tính.

Các mốc thời gian quan trọng về việc tuân thủ

  • Ngày 14 tháng 3 năm 2022 – các ứng dụng OAuth mới bị chặn sử dụng luồng địa chỉ IP Loopback
  • Ngày 1 tháng 8 năm 2022 – thông báo cảnh báo dành cho người dùng có thể được hiển thị cho các yêu cầu OAuth không tuân thủ
  • Ngày 31 tháng 8 năm 2022 – luồng địa chỉ IP Loopback bị chặn đối với ứng dụng OAuth gốc trên Android, ứng dụng Chrome và iOS được tạo trước ngày 14 tháng 3 năm 2022
  • Ngày 21 tháng 10 năm 2022 – tất cả ứng dụng hiện có sẽ bị chặn (bao gồm cả ứng dụng được miễn trừ)

Thông báo lỗi dành cho người dùng sẽ xuất hiện đối với các yêu cầu không tuân thủ. Thông báo này sẽ cho người dùng biết rằng ứng dụng bị chặn trong khi hiển thị email hỗ trợ mà bạn đã đăng ký trong màn hình xin phép bằng OAuth trong Google API Console.

Có hai bước chính cần hoàn tất để thực hiện quá trình di chuyển:
  1. Xác định xem bạn có bị ảnh hưởng hay không.
  2. Hãy chuyển sang một phương thức thay thế được hỗ trợ nếu bạn bị ảnh hưởng.

Xác định xem bạn có bị ảnh hưởng hay không

Xem lại loại mã ứng dụng khách OAuth

Chuyển đến của và xem loại mã ứng dụng khách OAuth trong phần Mã ứng dụng khách OAuth 2.0. Đó sẽ là một trong những loại sau: Ứng dụng web, Android, iOS, Universal Windows Platform (UWP), Ứng dụng Chrome, TV và thiết bị đầu vào có giới hạn, Ứng dụng dành cho máy tính.

Hãy chuyển sang bước tiếp theo nếu loại ứng dụng của bạn là Android, ứng dụng Chrome hoặc iOS và bạn đang sử dụng quy trình địa chỉ IP loopback.

Bạn không cần làm gì liên quan đến việc ngừng sử dụng này nếu đang sử dụng quy trình địa chỉ IP loopback trên ứng dụng OAuth dành cho máy tính vì việc sử dụng loại ứng dụng OAuth đó sẽ tiếp tục được hỗ trợ.

Cách xác định xem ứng dụng của bạn có đang sử dụng luồng địa chỉ IP vòng lặp hay không

Kiểm tra mã ứng dụng hoặc lệnh gọi mạng đi (trong trường hợp ứng dụng của bạn đang sử dụng thư viện OAuth) để xác định xem yêu cầu uỷ quyền OAuth của Google mà ứng dụng của bạn đang thực hiện có sử dụng các giá trị URI chuyển hướng vòng lặp hay không.

Kiểm tra mã ứng dụng

Xem lại phần mã ứng dụng mà bạn đang thực hiện lệnh gọi đến điểm cuối uỷ quyền OAuth của Google và xác định xem tham số redirect_uri có bất kỳ giá trị nào sau đây hay không:
  • redirect_uri=http://127.0.0.1:<port>, ví dụ: redirect_uri=http://127.0.0.1:3000
  • redirect_uri=http://[::1]:<port>, ví dụ: redirect_uri=http://[::1]:3000
  • redirect_uri=http://localhost:<port>, ví dụ: redirect_uri=http://localhost:3000
Yêu cầu luồng chuyển hướng địa chỉ IP vòng lặp mẫu sẽ có dạng như sau:
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

Kiểm tra lệnh gọi mạng đi

Phương thức kiểm tra lệnh gọi mạng sẽ khác nhau tuỳ thuộc vào loại ứng dụng của bạn.
Trong khi kiểm tra các lệnh gọi mạng, hãy tìm các yêu cầu được gửi đến điểm cuối uỷ quyền của Google OAuth và xác định xem tham số redirect_uri có bất kỳ giá trị nào sau đây hay không:
  • redirect_uri=http://127.0.0.1:<port>, ví dụ: redirect_uri=http://127.0.0.1:3000
  • redirect_uri=http://[::1]:<port>, ví dụ: redirect_uri=http://[::1]:3000
  • redirect_uri=http://localhost:<port>, ví dụ: redirect_uri=http://localhost:3000
Yêu cầu luồng chuyển hướng địa chỉ IP vòng lặp mẫu sẽ có dạng như sau:
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

Di chuyển sang một phương thức thay thế được hỗ trợ

Ứng dụng di động (Android / iOS)

Nếu xác định rằng ứng dụng của bạn đang sử dụng luồng địa chỉ IP vòng lặp với loại ứng dụng OAuth Android hoặc iOS, bạn nên chuyển sang sử dụng các SDK được đề xuất (Android, iOS).

SDK này giúp bạn dễ dàng truy cập vào các API của Google và xử lý tất cả các lệnh gọi đến điểm cuối uỷ quyền OAuth 2.0 của Google.

Các đường liên kết đến tài liệu bên dưới cung cấp thông tin về cách sử dụng các SDK được đề xuất để truy cập vào API của Google mà không cần sử dụng URI chuyển hướng địa chỉ IP vòng lặp.

Truy cập vào API của Google trên Android

Quyền truy cập phía máy khách

Ví dụ sau đây cho biết cách truy cập vào các API của Google ở phía ứng dụng trên Android bằng cách sử dụng Thư viện Android Dịch vụ nhận dạng của Google được đề xuất.

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

Truyền authorizationResult vào phương thức đã xác định để lưu nội dung vào thư mục ổ của người dùng. authorizationResult có phương thức getAccessToken() trả về mã thông báo truy cập.

Quyền truy cập phía máy chủ (khi không có mạng)
Ví dụ sau đây cho thấy cách truy cập vào các API của Google ở phía máy chủ trên Android.
  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 có phương thức getServerAuthCode() trả về mã uỷ quyền mà bạn có thể gửi đến phần phụ trợ để lấy mã truy cập và làm mới.

Truy cập vào API của Google trong ứng dụng iOS

Quyền truy cập phía máy khách

Ví dụ dưới đây cho thấy cách truy cập vào các API của Google ở phía máy khách trên 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()
}

Sử dụng mã truy cập để gọi API bằng cách đưa mã truy cập vào tiêu đề của yêu cầu REST hoặc gRPC (Authorization: Bearer ACCESS_TOKEN) hoặc bằng cách sử dụng trình uỷ quyền trình tìm nạp (GTMFetcherAuthorizationProtocol) với thư viện ứng dụng API của Google cho Objective-C cho REST.

Xem lại hướng dẫn truy cập phía máy khách về cách truy cập vào các API của Google ở phía máy khách. về cách truy cập vào các API của Google ở phía máy khách.

Quyền truy cập phía máy chủ (khi không có mạng)
Ví dụ bên dưới cho thấy cách truy cập vào các API của Google ở phía máy chủ để hỗ trợ ứng dụng 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
}

Xem lại hướng dẫn truy cập phía máy chủ về cách truy cập vào API của Google từ phía máy chủ.

Ứng dụng Chrome

Nếu xác định rằng ứng dụng của bạn đang sử dụng luồng địa chỉ IP loopback trên ứng dụng Chrome, bạn nên chuyển sang sử dụng API Chrome Identity.

Ví dụ bên dưới cho thấy cách lấy tất cả thông tin liên hệ của người dùng mà không cần sử dụng URI chuyển hướng địa chỉ IP vòng lặp.

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

Xem lại hướng dẫn về API Chrome Identity để biết thêm thông tin về cách truy cập để xác thực người dùng và gọi các điểm cuối của Google bằng API Chrome Identity.