ภาพรวม
เมื่อวันที่ 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
- ตรวจสอบว่าคุณได้รับผลกระทบหรือไม่
- เปลี่ยนไปใช้วิธีอื่นที่รองรับหากคุณได้รับผลกระทบ
ตรวจสอบว่าคุณได้รับผลกระทบหรือไม่
ตรวจสอบประเภทรหัสไคลเอ็นต์ 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 หรือไม่
ตรวจสอบโค้ดแอปพลิเคชัน
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
https://accounts.google.com/o/oauth2/v2/auth? redirect_uri=http://localhost:3000& response_type=code& scope=<SCOPES>& state=<STATE>& client_id=<CLIENT_ID>
ตรวจสอบการโทรออกผ่านเครือข่าย
- เว็บแอปพลิเคชัน - ตรวจสอบกิจกรรมเครือข่ายใน Chrome
- Android - ตรวจสอบการรับส่งข้อมูลในเครือข่ายด้วยเครื่องมือตรวจสอบเครือข่าย
-
แอป Chrome
- ไปที่หน้าส่วนขยาย Chrome
- เลือกช่องทําเครื่องหมายโหมดนักพัฒนาซอฟต์แวร์ที่มุมขวาบนของหน้าส่วนขยาย
- เลือกส่วนขยายที่ต้องการตรวจสอบ
- คลิกลิงก์หน้าพื้นหลังในส่วนตรวจสอบมุมมองของหน้าส่วนขยาย
- ป๊อปอัปเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จะเปิดขึ้นเพื่อให้คุณตรวจสอบการรับส่งข้อมูลในเครือข่ายได้ ในแท็บเครือข่าย
- iOS - การวิเคราะห์การรับส่งข้อมูล HTTP ด้วย Instruments
- แพลตฟอร์ม Universal Windows (UWP) - ตรวจสอบการรับส่งข้อมูลในเครือข่ายใน Visual Studio
- แอปบนเดสก์ท็อป - ใช้เครื่องมือจับภาพเครือข่าย พร้อมใช้งานสำหรับระบบปฏิบัติการที่แอปพัฒนาขึ้น
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
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 ที่แนะนํา
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
ไปยังเมธอดที่คุณกำหนดเพื่อบันทึกเนื้อหาไปยังโฟลเดอร์ไดรฟ์ของผู้ใช้ authorizationResult
มีเมธอด
getAccessToken()
ที่จะแสดงผลโทเค็นการเข้าถึง
การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)
ตัวอย่างต่อไปนี้แสดงวิธีเข้าถึง Google API ฝั่งเซิร์ฟเวอร์ใน AndroidListrequestedScopes = 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 ฝั่งเซิร์ฟเวอร์เพื่อรองรับไคลเอ็นต์ iOSGIDSignIn.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