ภาพรวม
เมื่อวันที่ 16 กุมภาพันธ์ 2022 เราได้ ประกาศแผนที่จะทำให้การโต้ตอบของ Google OAuth ปลอดภัยขึ้นโดยใช้ขั้นตอน 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 Consent Screen pageของ Google API Console และทำตามขั้นตอนถัดไปหากคุณใช้ ขั้นตอน OOB ในโปรเจ็กต์ที่มีสถานะการเผยแพร่ "ในเวอร์ชันที่ใช้งานจริง"
วิธีตรวจสอบว่าแอปของคุณใช้ขั้นตอน OOB หรือไม่
ตรวจสอบรหัสแอปหรือการโทรออกผ่านเครือข่าย (ในกรณีที่แอปใช้ไลบรารี OAuth) เพื่อดูว่า คำขอการให้สิทธิ์ของ Google OAuth ที่แอปของคุณดำเนินการอยู่โดยใช้ค่า URI การเปลี่ยนเส้นทาง OOB หรือไม่
ตรวจสอบโค้ดของแอปพลิเคชัน
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 Sign-In เพื่อเข้าถึง Google API โดยไม่ต้องใช้ 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
) หรือใช้ผู้ให้สิทธิ์โปรแกรม Googlebot จำลอง (GTMFetcherAuthorizationProtocol
) กับ
ไลบรารีของไคลเอ็นต์ Google APIs สำหรับ Objective-C สําหรับ REST
อ่านคู่มือการเข้าถึงฝั่งไคลเอ็นต์เกี่ยวกับวิธีเข้าถึง Google APIs ในฝั่งไคลเอ็นต์ เกี่ยวกับวิธีเข้าถึง 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 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 การเปลี่ยนเส้นทาง ใน Credentials page ของ Google API Console
ข้อมูลโค้ดด้านล่างแสดงตัวอย่าง 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
)