คําแนะนําในการย้ายข้อมูลนอกขอบเขต (OOB)

ภาพรวม

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

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

ข้อความเตือนที่แสดงต่อผู้ใช้อาจปรากฏสําหรับคําขอที่ไม่เป็นไปตามข้อกําหนด 1 เดือนก่อน เช่น วันที่ 5 กันยายน 2022 ซึ่งเป็นกระบวนการ OOB โดยสมบูรณ์โดยสมบูรณ์ ข้อความนี้จะแจ้งให้ผู้ใช้ทราบว่าแอปนั้นอาจถูกบล็อกในไม่ช้า ขณะที่แสดงอีเมลสนับสนุนที่คุณลงทะเบียนไว้ในหน้าจอคํายินยอม OAuth ในคอนโซล Google API

คุณรับทราบข้อความเตือนที่แสดงแก่ผู้ใช้และระงับได้โดยการส่งพารามิเตอร์การค้นหาในการเรียกใช้การให้สิทธิ์ดังที่แสดงด้านล่าง
  • ไปที่โค้ดในแอปที่คุณส่งคําขอไปยังปลายทางการให้สิทธิ์ OAuth 2.0 ของ Google
  • เพิ่มพารามิเตอร์ ack_oob_shutdown ที่มีค่าของวันที่บังคับใช้: 2022-10-03 ในคําขอโฟลว์เปลี่ยนเส้นทาง ตัวอย่าง:
    ack_oob_shutdown=2022-10-03
กระบวนการย้ายข้อมูลมี 2 ขั้นตอนหลักๆ ดังนี้
  1. ตรวจสอบว่าได้รับผลกระทบหรือไม่
  2. ย้ายข้อมูลไปยังทางเลือกที่ปลอดภัยกว่าหากได้รับผลกระทบ

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

การเลิกใช้งานนี้ใช้ได้เฉพาะกับแอปเวอร์ชันที่ใช้งานจริง (เช่น แอปที่ตั้งสถานะการเผยแพร่เป็นเวอร์ชันที่ใช้งานจริง กระบวนการจะยังทํางานต่อไปสําหรับแอปที่มีสถานะการทดสอบการเผยแพร่

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

วิธีตรวจสอบว่าแอปของคุณใช้กระบวนการ OOB หรือไม่

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

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

ตรวจสอบส่วนของโค้ดแอปพลิเคชันที่คุณใช้เรียกปลายทางการให้สิทธิ์ของ Google OAuth และระบุว่าพารามิเตอร์ redirect_uri มีค่าใดค่าหนึ่งต่อไปนี้หรือไม่
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
ตัวอย่างคําขอขั้นตอนเปลี่ยนเส้นทาง 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>

ตรวจสอบการโทรออกของเครือข่าย

วิธีการตรวจสอบการเรียกเครือข่ายจะแตกต่างกันไปตามประเภทของไคลเอ็นต์แอปพลิเคชัน
ขณะตรวจสอบการเรียกจากเครือข่าย ให้มองหาคําขอที่ส่งไปยังปลายทางการให้สิทธิ์ของ Google OAuth และพิจารณาว่าพารามิเตอร์ redirect_uri มีค่าใดค่าหนึ่งต่อไปนี้หรือไม่
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob
  • redirect_uri=urn:ietf:wg:oauth:2.0:oob:auto
  • redirect_uri=oob
ตัวอย่างคําขอขั้นตอนเปลี่ยนเส้นทาง 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 API โดยไม่ต้องใช้ URI การเปลี่ยนเส้นทาง OOB

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

การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)
ตัวอย่างด้านล่างแสดงวิธีเข้าถึง Google API ในฝั่งเซิร์ฟเวอร์บน Android
Task<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 API จากฝั่งเซิร์ฟเวอร์ได้ในคําแนะนําการเข้าถึงฝั่งเซิร์ฟเวอร์

เข้าถึง Google API ในแอป iOS

สิทธิ์เข้าถึงฝั่งไคลเอ็นต์

ตัวอย่างด้านล่างแสดงวิธีเข้าถึง Google API ในฝั่งไคลเอ็นต์บน 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 API ในฝั่งไคลเอ็นต์ได้จากคู่มือการเข้าถึงฝั่งไคลเอ็นต์ เกี่ยวกับวิธีเข้าถึง Google API ในฝั่งไคลเอ็นต์

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

หากพบว่าแอปใช้ 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 API จากฝั่งเซิร์ฟเวอร์ได้ที่คําแนะนําเกี่ยวกับเว็บแอปฝั่งเซิร์ฟเวอร์

สิทธิ์เข้าถึงฝั่งไคลเอ็นต์

ข้อมูลโค้ดด้านล่างใน 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 API จากฝั่งไคลเอ็นต์ได้จากคู่มือเว็บแอปฝั่งไคลเอ็นต์

ไคลเอ็นต์เดสก์ท็อป

หากคุณเห็นว่าแอปใช้โฟลว์ OOB ของไคลเอ็นต์เดสก์ท็อป คุณควรเปลี่ยนไปใช้ขั้นตอนที่อยู่ IP แบบวนกลับ (localhost หรือ 127.0.0.1)