ภาพรวม
ในวันที่ 16 กุมภาพันธ์ 2022 เราได้ ประกาศแผนที่จะทำให้การโต้ตอบ OAuth ของ Google ปลอดภัยยิ่งขึ้นด้วยการใช้ขั้นตอน OAuth ที่ปลอดภัยมากขึ้น คู่มือนี้จะช่วยให้คุณเข้าใจการเปลี่ยนแปลงและขั้นตอนที่จำเป็นในการย้ายข้อมูลจากขั้นตอน OAuth นอกขอบเขต (OOB) ไปยังทางเลือกที่รองรับให้สำเร็จ
ซึ่งใช้เป็นมาตรการป้องกันฟิชชิงและการโจมตีแบบแอบอ้างเป็นแอป ในระหว่างการโต้ตอบกับปลายทางการให้สิทธิ์ OAuth 2.0 ของ Google
OOB คืออะไร
OAuth นอกขอบเขต (OOB) หรือที่เรียกว่าตัวเลือกการคัดลอก/วางด้วยตนเอง เป็นขั้นตอนแบบเดิมที่พัฒนาขึ้นเพื่อรองรับไคลเอ็นต์แบบเนทีฟที่ไม่มี URI การเปลี่ยนเส้นทางเพื่อยอมรับข้อมูลเข้าสู่ระบบหลังจากที่ผู้ใช้อนุมัติคำขอความยินยอม OAuth ขั้นตอน OOB ก่อให้เกิดความเสี่ยงต่อฟิชชิงจากระยะไกล และลูกค้าต้องย้ายข้อมูลไปยังวิธีการอื่นเพื่อป้องกันช่องโหว่นี้เราจะเลิกใช้งานกระบวนการ OOB สำหรับไคลเอ็นต์ทุกประเภท ได้แก่ เว็บแอปพลิเคชัน, Android, iOS, Universal Windows Platform (UWP), แอป Chrome, ทีวีและอุปกรณ์อินพุตแบบจำกัด รวมถึงแอปบนเดสก์ท็อป
วันที่ที่สำคัญในการปฏิบัติตามข้อกำหนด
- 28 กุมภาพันธ์ 2022 - บล็อกการใช้งาน OAuth ใหม่สำหรับขั้นตอน OOB
- 5 กันยายน 2022 - ข้อความเตือนที่แสดงต่อผู้ใช้อาจแสดงสำหรับคำขอ OAuth ที่ไม่เป็นไปตามข้อกำหนด
- 3 ตุลาคม 2022 - เราจะเลิกใช้งานขั้นตอน OOB สำหรับไคลเอ็นต์ OAuth ที่สร้างขึ้นก่อนวันที่ 28 กุมภาพันธ์ 2022
- 31 มกราคม 2023 - ลูกค้าที่มีอยู่ทั้งหมดถูกบล็อก (รวมถึงลูกค้าที่ได้รับการยกเว้น)
ข้อความแสดงข้อผิดพลาดที่แสดงต่อผู้ใช้จะแสดงสำหรับคำขอที่ไม่เป็นไปตามข้อกำหนด ข้อความจะแจ้งให้ผู้ใช้ทราบว่าแอปถูกบล็อกขณะแสดงอีเมลสนับสนุนที่คุณได้ลงทะเบียนไว้ในหน้าจอขอความยินยอม OAuth ในคอนโซล Google API
- ตรวจสอบว่าคุณได้รับผลกระทบหรือไม่
- หากได้รับผลกระทบ ให้ย้ายข้อมูลไปยังวิธีอื่นที่ปลอดภัยกว่า
ตรวจสอบว่าคุณได้รับผลกระทบหรือไม่
การเลิกใช้งานนี้มีผลเฉพาะกับแอปเวอร์ชันที่ใช้งานจริงเท่านั้น (ซึ่งก็คือแอปที่ตั้งค่าสถานะการเผยแพร่เป็น ในเวอร์ชันที่ใช้งานจริง) ขั้นตอนดังกล่าวจะยังทำงานต่อไปสำหรับแอปที่มี สถานะการเผยแพร่การทดสอบ
ตรวจสอบสถานะการเผยแพร่ใน OAuth ของ และดำเนินการต่อขั้นตอนถัดไปหากคุณใช้ ขั้นตอน OOB ในโปรเจ็กต์ที่มีสถานะการเผยแพร่ "ใช้เวอร์ชันที่ใช้งานจริง"
วิธีตรวจสอบว่าแอปของคุณใช้ขั้นตอน OOB หรือไม่
ตรวจสอบโค้ดของแอปหรือสายโทรออกผ่านเครือข่าย (ในกรณีที่แอปใช้ไลบรารี OAuth) เพื่อดูว่า คำขอการให้สิทธิ์ของ Google OAuthใช้ URI การเปลี่ยนเส้นทางหรือไม่
ตรวจสอบโค้ดของแอปพลิเคชัน
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 ด้วยเครื่องมือ
- 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)
หากคุณพิจารณาแล้วว่าแอปใช้ขั้นตอน OOB กับประเภทไคลเอ็นต์ OAuth สำหรับ Android หรือ iOS คุณควรย้ายข้อมูลไปใช้ SDK อุปกรณ์เคลื่อนที่ Google Sign-In (Android, iOS)
SDK ช่วยให้เข้าถึง Google API และจัดการการเรียกใช้ทั้งหมดไปยังปลายทางการให้สิทธิ์ OAuth 2.0 ของ Google ได้อย่างง่ายดาย
ลิงก์เอกสารประกอบด้านล่างให้ข้อมูลเกี่ยวกับวิธีใช้ SDK การลงชื่อเข้าใช้ของ Google เพื่อเข้าถึง Google APIs โดยไม่ต้องใช้ URI การเปลี่ยนเส้นทาง OOB
เข้าถึง Google APIs บน Android
การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)
ตัวอย่างด้านล่างแสดงวิธี เข้าถึง Google APIs จากฝั่งเซิร์ฟเวอร์บน AndroidTask<GoogleSignInAccount> task = GoogleSignIn.getSignedInAccountFromIntent(data); try { GoogleSignInAccount account = task.getResult(ApiException.class); // request a one-time authorization code that your server exchanges for an // access token and sometimes refresh token String authCode = account.getServerAuthCode(); // Show signed-in UI updateUI(account); // TODO(developer): send code to server and exchange for access/refresh/ID tokens } catch (ApiException e) { Log.w(TAG, "Sign-in failed", e); updateUI(null); }
อ่านคู่มือการเข้าถึงฝั่งเซิร์ฟเวอร์เพื่อดูวิธีเข้าถึง Google APIs จากฝั่งเซิร์ฟเวอร์
เข้าถึง 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 APIs สำหรับ Objective-C สำหรับ REST
อ่านคู่มือการเข้าถึงฝั่งไคลเอ็นต์เกี่ยวกับวิธีเข้าถึง Google APIs ในฝั่งไคลเอ็นต์ เกี่ยวกับวิธีเข้าถึง Google APIs ในฝั่งไคลเอ็นต์
การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)
ตัวอย่างด้านล่างแสดงวิธีเข้าถึง Google APIs ในฝั่งเซิร์ฟเวอร์เพื่อรองรับไคลเอ็นต์ 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 APIs จากฝั่งเซิร์ฟเวอร์
ไคลเอ็นต์แอป Chrome
หากคุณทราบว่าแอปกำลังใช้ขั้นตอน OOB ในไคลเอ็นต์แอป Chrome ให้ย้ายข้อมูลไปใช้ Chrome Identity API
ตัวอย่างด้านล่างแสดงวิธีรับรายชื่อติดต่อทั้งหมดของผู้ใช้โดยไม่ต้องใช้ URI การเปลี่ยนเส้นทาง OOB
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
เว็บแอปพลิเคชัน
หากคุณพิจารณาว่าแอปใช้ขั้นตอน OOB สำหรับเว็บแอปพลิเคชัน คุณควรย้ายข้อมูลไปใช้ไลบรารีของไคลเอ็นต์ Google API รายการใดรายการหนึ่งของเรา ดูไลบรารีของไคลเอ็นต์สำหรับภาษาโปรแกรมต่างๆ ได้ที่นี่
ไลบรารีช่วยให้เข้าถึง Google API และจัดการการเรียกใช้ปลายทางทั้งหมดของ Google ได้อย่างง่ายดาย
การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)
- ยืนเซิร์ฟเวอร์และกำหนดปลายทางที่เข้าถึงได้แบบสาธารณะ (URI การเปลี่ยนเส้นทาง) เพื่อรับรหัสการให้สิทธิ์
- กำหนดค่า URI การเปลี่ยนเส้นทาง ใน ของ
ข้อมูลโค้ดด้านล่างแสดงตัวอย่าง NodeJS ที่ใช้ Google Drive API เพื่อแสดงไฟล์ Google ไดรฟ์ของผู้ใช้ในฝั่งเซิร์ฟเวอร์โดยไม่ต้องใช้ URI การเปลี่ยนเส้นทาง OOB
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 APIs จากฝั่งเซิร์ฟเวอร์
การเข้าถึงฝั่งไคลเอ็นต์
ข้อมูลโค้ดด้านล่างใน 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 APIs จากฝั่งไคลเอ็นต์
ไคลเอ็นต์บนเดสก์ท็อป
หากคุณพิจารณาว่าแอปใช้ขั้นตอน OOB ในไคลเอ็นต์บนเดสก์ท็อป คุณควรย้ายข้อมูลไปใช้
โฟลว์ที่อยู่ IP แบบ Loopback (localhost
หรือ 127.0.0.1
)