คู่มือการย้ายข้อมูลโฟลว์ IP ของ Loopback

ภาพรวม

เมื่อวันที่ 16 กุมภาพันธ์ 2022 เราได้ ประกาศแผนที่จะทำให้การโต้ตอบกับ Google OAuth ปลอดภัยยิ่งขึ้นโดยใช้ขั้นตอน OAuth ที่ปลอดภัยยิ่งขึ้น คู่มือนี้จะช่วยให้คุณเข้าใจการเปลี่ยนแปลงและขั้นตอนที่จําเป็นในการย้ายข้อมูลจากโฟลว์ที่อยู่ IP ของพอร์ต loopback ไปยังทางเลือกที่รองรับได้อย่างสําเร็จ

การดำเนินการนี้เป็นมาตรการป้องกันฟิชชิงและการโจมตีด้วยการแอบอ้างเป็นแอประหว่างการโต้ตอบกับปลายทางการให้สิทธิ์ OAuth 2.0 ของ Google

ขั้นตอนการกำหนดที่อยู่ IP ของ Loopback คืออะไร

ขั้นตอนการใช้ที่อยู่ IP ของพอร์ต loopback รองรับการใช้ที่อยู่ IP ของพอร์ต loopback หรือ localhost เป็นส่วนประกอบโฮสต์ของ URI การเปลี่ยนเส้นทางที่จะส่งข้อมูลเข้าสู่ระบบไปหลังจากที่ผู้ใช้อนุมัติคําขอความยินยอม OAuth ขั้นตอนนี้เสี่ยงต่อการโจมตีแบบแทรกกลางการสื่อสาร ซึ่งแอปที่เป็นอันตรายที่เข้าถึงอินเทอร์เฟซ Loopback เดียวกันในระบบปฏิบัติการบางระบบอาจขัดขวางการตอบกลับจากเซิร์ฟเวอร์การให้สิทธิ์ไปยัง URI การเปลี่ยนเส้นทางที่ระบุ และเข้าถึงรหัสการให้สิทธิ์ได้

เราจะเลิกใช้งานโฟลว์ที่อยู่ IP ของ Loopback สำหรับประเภทไคลเอ็นต์ OAuth ของ iOS, Android และ Chrome บนอุปกรณ์เคลื่อนที่ แต่ระบบจะยังคงรองรับแอปบนเดสก์ท็อปต่อไป

วันที่สำคัญในการปฏิบัติตามข้อกำหนด

  • 14 มีนาคม 2022 - บล็อกไคลเอ็นต์ OAuth ใหม่ไม่ให้ใช้ขั้นตอนที่อยู่ IP ของ Loopback
  • 1 สิงหาคม 2022 - ระบบอาจแสดงข้อความเตือนต่อผู้ใช้สำหรับคำขอ OAuth ที่ไม่เป็นไปตามข้อกำหนด
  • 31 สิงหาคม 2022 - ระบบจะบล็อกขั้นตอนที่อยู่ IP ของ Loopback สำหรับไคลเอ็นต์ OAuth ของ iOS, แอป Chrome และ Android ดั้งเดิมที่สร้างก่อนวันที่ 14 มีนาคม 2022
  • 21 ตุลาคม 2022 - ระบบจะบล็อกลูกค้าเดิมทั้งหมด (รวมถึงลูกค้าที่ได้รับการยกเว้น)

ระบบจะแสดงข้อความแสดงข้อผิดพลาดต่อผู้ใช้สำหรับคำขอที่ไม่เป็นไปตามข้อกำหนด ข้อความจะแจ้งให้ผู้ใช้ทราบว่าแอปถูกบล็อกขณะแสดงอีเมลสนับสนุนที่คุณลงทะเบียนไว้ในหน้าจอขอความยินยอม OAuth ในคอนโซล Google API

ขั้นตอนหลักๆ 2 ขั้นตอนที่ต้องทำเพื่อย้ายข้อมูลให้เสร็จสมบูรณ์มีดังนี้
  1. ตรวจสอบว่าคุณได้รับผลกระทบหรือไม่
  2. เปลี่ยนไปใช้วิธีอื่นที่รองรับหากคุณได้รับผลกระทบ

ตรวจสอบว่าคุณได้รับผลกระทบหรือไม่

ตรวจสอบประเภทรหัสไคลเอ็นต์ OAuth

ไปที่ ของ และดูประเภทรหัสไคลเอ็นต์ OAuth ในส่วนรหัสไคลเอ็นต์ OAuth 2.0 โดยจะเป็นแพลตฟอร์มใดแพลตฟอร์มหนึ่งต่อไปนี้ เว็บแอปพลิเคชัน, Android, iOS, Universal Windows Platform (UWP), แอป Chrome, ทีวีและอุปกรณ์อินพุตแบบจำกัด และแอปบนเดสก์ท็อป

ไปยังขั้นตอนถัดไปหากประเภทไคลเอ็นต์คือ Android, แอป Chrome หรือ iOS และคุณใช้ขั้นตอนที่อยู่ IP ของ Loopback

คุณไม่จำเป็นต้องดำเนินการใดๆ เกี่ยวกับการเลิกใช้งานนี้หากคุณใช้ขั้นตอนที่อยู่ IP ของ Loopback ในไคลเอ็นต์ OAuth ของแอปเดสก์ท็อป เนื่องจากเราจะยังคงรองรับการใช้งานกับไคลเอ็นต์ OAuth ประเภทดังกล่าวต่อไป

วิธีตรวจสอบว่าแอปใช้โฟลว์ที่อยู่ IP ของพอร์ต loopback หรือไม่

ตรวจสอบโค้ดแอปหรือการเรียกใช้เครือข่ายขาออก (ในกรณีที่แอปใช้ไลบรารี OAuth) เพื่อดูว่า คำขอการให้สิทธิ์ Google OAuth ที่แอปส่งใช้ค่า URI การเปลี่ยนเส้นทางแบบ Loopback หรือไม่

ตรวจสอบโค้ดแอปพลิเคชัน

ตรวจสอบส่วนโค้ดแอปพลิเคชันที่คุณเรียกใช้ Google OAuth endpoint การให้สิทธิ์ และดูว่าพารามิเตอร์ 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 ของลูปแบ็กจะมีลักษณะดังนี้
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 ของลูปแบ็กจะมีลักษณะดังต่อไปนี้
https://accounts.google.com/o/oauth2/v2/auth?
redirect_uri=http://localhost:3000&
response_type=code&
scope=<SCOPES>&
state=<STATE>&
client_id=<CLIENT_ID>

เปลี่ยนไปใช้วิธีอื่นที่รองรับ

โปรแกรมไคลเอ็นต์บนอุปกรณ์เคลื่อนที่ (Android / iOS)

หากพบว่าแอปของคุณใช้โฟลว์ที่อยู่ IP ของ Loopback กับประเภทไคลเอ็นต์ OAuth ของ Android หรือ iOS คุณควรเปลี่ยนไปใช้ SDK ที่แนะนํา (Android, iOS)

SDK ช่วยให้เข้าถึง Google API ได้ง่ายและจัดการการเรียกใช้ปลายทางการให้สิทธิ์ OAuth 2.0 ทั้งหมดของ Google

ลิงก์เอกสารประกอบด้านล่างมีข้อมูลเกี่ยวกับวิธีใช้ SDK ที่แนะนําเพื่อเข้าถึง Google API โดยไม่ต้องใช้ที่อยู่ IP ของลูปแบ็กหรือ URI เปลี่ยนเส้นทาง

เข้าถึง Google API ใน Android

การเข้าถึงฝั่งไคลเอ็นต์

ตัวอย่างต่อไปนี้แสดงวิธีเข้าถึง Google API ฝั่งไคลเอ็นต์ใน Android โดยใช้ไลบรารี Android ของบริการข้อมูลประจำตัวของ Google ที่แนะนํา

  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() ที่จะแสดงผลโทเค็นการเข้าถึง

การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)
ตัวอย่างต่อไปนี้แสดงวิธีเข้าถึง Google API ฝั่งเซิร์ฟเวอร์ใน 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 มีเมธอด getServerAuthCode() ที่จะแสดงผลรหัสการให้สิทธิ์ซึ่งคุณสามารถส่งไปยังแบ็กเอนด์เพื่อรับโทเค็นการเข้าถึงและโทเค็นการรีเฟรช

เข้าถึง 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()
}

ใช้โทเค็นการเข้าถึงเพื่อเรียก API โดยใส่โทเค็นการเข้าถึงในส่วนหัวของคําขอ REST หรือ gRPC (Authorization: Bearer ACCESS_TOKEN) หรือใช้ผู้ให้สิทธิ์เครื่องมือค้นหา (GTMFetcherAuthorizationProtocol) กับ ไลบรารีของไคลเอ็นต์ Google API สําหรับ Objective-C สําหรับ REST

อ่านคู่มือการเข้าถึงฝั่งไคลเอ็นต์เกี่ยวกับวิธีเข้าถึง Google API ฝั่งไคลเอ็นต์ เกี่ยวกับวิธีเข้าถึง Google APIs ฝั่งไคลเอ็นต์

การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)
ตัวอย่างด้านล่างแสดงวิธีเข้าถึง Google 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
}

อ่านคู่มือการเข้าถึงฝั่งเซิร์ฟเวอร์เกี่ยวกับวิธีเข้าถึง Google API จากฝั่งเซิร์ฟเวอร์

ไคลเอ็นต์แอป Chrome

หากพบว่าแอปของคุณใช้ขั้นตอนที่อยู่ IP ของ Loopback ในไคลเอ็นต์แอป Chrome คุณควรเปลี่ยนไปใช้ Chrome Identity API

ตัวอย่างด้านล่างแสดงวิธีรับรายชื่อติดต่อของผู้ใช้ทั้งหมดโดยไม่ต้องใช้ URI การเปลี่ยนเส้นทางที่อยู่ IP ของลูปแบ็ก

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