การใช้โมเดลโทเค็น

ไลบรารี JavaScript ของ google.accounts.oauth2 ช่วยให้คุณแจ้งขอความยินยอม จากผู้ใช้ และรับโทเค็นเพื่อการเข้าถึงเพื่อใช้กับข้อมูลผู้ใช้ได้ ซึ่งขึ้นอยู่กับขั้นตอนการให้สิทธิ์โดยนัยของ OAuth 2.0 และออกแบบมาเพื่อให้คุณสามารถเรียกใช้ Google API ได้โดยตรงโดยใช้ REST และ CORS หรือใช้ไลบรารีของไคลเอ็นต์ Google API สําหรับ JavaScript (หรือที่เรียกว่า gapi.client) เพื่อให้เข้าถึง API ที่ซับซ้อนและยืดหยุ่นได้ง่ายขึ้น

ก่อนที่จะเข้าถึงข้อมูลผู้ใช้ที่ได้รับการคุ้มครองจากเบราว์เซอร์ ผู้ใช้ในเว็บไซต์ของคุณจะทริกเกอร์ตัวเลือกบัญชีผู้ใช้ การลงชื่อเข้าใช้ และความยินยอมของ Google\#39; และสุดท้ายเซิร์ฟเวอร์ OAuth ของ Google จะส่งคืนโทเค็นการเข้าถึงไปยังเว็บแอปของคุณ

ในโมเดลการให้สิทธิ์แบบโทเค็น คุณไม่จําเป็นต้องจัดเก็บโทเค็นการรีเฟรชต่อผู้ใช้แต่ละรายในเซิร์ฟเวอร์แบ็กเอนด์

เราขอแนะนําให้คุณทําตามแนวทางที่ระบุไว้ที่นี่แทนเทคนิคซึ่งครอบคลุมโดยคู่มือ OAuth 2.0 สําหรับเว็บแอปพลิเคชันฝั่งไคลเอ็นต์แบบเก่า

ตั้งค่า

ค้นหาหรือสร้างรหัสไคลเอ็นต์โดยทําตามขั้นตอนที่อธิบายไว้ในคู่มือรับรหัสไคลเอ็นต์ Google API ต่อไป ให้เพิ่มไลบรารีของไคลเอ็นต์ ลงในหน้าเว็บในเว็บไซต์ที่จะเรียกใช้ Google API สุดท้าย ให้เริ่ม ไคลเอ็นต์โทเค็น โดยปกติ การดําเนินการนี้จะทําในเครื่องจัดการ onload ของไลบรารีของไคลเอ็นต์

เริ่มต้นไคลเอ็นต์โทเค็น

โทรหา initTokenClient() เพื่อเริ่มต้นไคลเอ็นต์โทเค็นใหม่ด้วยรหัสไคลเอ็นต์ของเว็บแอป หรืออาจรวมรายการขอบเขตอย่างน้อย 1 รายการที่ผู้ใช้ต้องการเข้าถึงก็ได้ ดังนี้

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  callback: (response) => {
    ...
  },
});

ทริกเกอร์โฟลว์โทเค็น OAuth 2.0

ใช้เมธอด requestAccessToken() เพื่อทริกเกอร์โฟลว์ UX ของโทเค็น แล้วรับโทเค็นเพื่อการเข้าถึง Google จะแจ้งให้ผู้ใช้ดําเนินการต่อไปนี้

  • เลือกบัญชี
  • ลงชื่อเข้าใช้บัญชี Google หากยังไม่ได้ลงชื่อเข้าใช้
  • ให้คํายินยอมสําหรับเว็บแอปในการเข้าถึงขอบเขตที่ขอแต่ละรายการ

ท่าทางสัมผัสของผู้ใช้จะทริกเกอร์โฟลว์ของโทเค็น ดังนี้ <button onclick="client.requestAccessToken();">Authorize me</button>

จากนั้น Google จะส่งกลับ TokenResponse ที่มีโทเค็นเพื่อการเข้าถึงและรายการของขอบเขตที่ผู้ใช้ให้สิทธิ์เข้าถึงหรือข้อผิดพลาดไปยังเครื่องจัดการการเรียกกลับ

ผู้ใช้อาจปิดหน้าต่างตัวเลือกบัญชีหรือหน้าต่างลงชื่อเข้าใช้ ซึ่งในกรณีนี้ระบบจะไม่เรียกใช้ฟังก์ชันเรียกกลับ

การออกแบบและประสบการณ์ของผู้ใช้สําหรับแอปของคุณควรใช้งานหลังจากที่คุณตรวจสอบนโยบาย OAuth 2.0 ของ Google อย่างละเอียดแล้วเท่านั้น นโยบายเหล่านี้ครอบคลุมการใช้งานในหลายขอบเขต วิธีการ และวิธีการจัดการความยินยอมของผู้ใช้ และอื่นๆ

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

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

การให้สิทธิ์ที่เพิ่มขึ้น

สําหรับเว็บแอป สถานการณ์ระดับสูง 2 ระดับต่อไปนี้จะแสดงให้เห็นถึงการให้สิทธิ์เพิ่มขึ้นโดยใช้

  • แอป Ajax แบบหน้าเดียวที่มักมีการใช้ XMLHttpRequest กับการเข้าถึงทรัพยากรแบบไดนามิก
  • หน้าเว็บหลายหน้าจะแยกและใช้ทรัพยากรในแต่ละหน้าแยกกัน

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

อาแจ๊กซ์

เพิ่มการรองรับแอปที่เพิ่มขึ้นด้วยการเรียก requestAccessToken() หลายครั้งและใช้พารามิเตอร์ OverridableTokenClientConfig'sscope เพื่อขอขอบเขตแต่ละรายการ ณ เวลาที่ต้องการและเมื่อจําเป็นเท่านั้น ในตัวอย่างนี้ ทรัพยากรจะขอและมองเห็นได้หลังจากที่ท่าทางสัมผัสของผู้ใช้ขยายส่วนเนื้อหาที่ยุบแล้วเท่านั้น

แอป Ajax
เริ่มต้นไคลเอ็นต์โทเค็นเมื่อโหลดหน้าเว็บ ดังนี้
        const client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_GOOGLE_CLIENT_ID',
          callback: "onTokenResponse",
        });
      
ขอความยินยอมและโทเค็นการเข้าถึงผ่านท่าทางสัมผัสของผู้ใช้ แล้วคลิก `+` เพื่อเปิด:

เอกสารสําหรับอ่าน

แสดงเอกสารล่าสุด

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/documents.readonly'
             })
           );
        

กิจกรรมที่กำลังจะมีขึ้น

แสดงข้อมูลปฏิทิน

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/calendar.readonly'
             })
           );
        

แสดงรูปภาพ

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/photoslibrary.readonly'
             })
           );
        

การเรียก requestAccessToken แต่ละครั้งจะทริกเกอร์ช่วงความยินยอมของผู้ใช้ แอปจะมีสิทธิ์เข้าถึงเฉพาะทรัพยากรที่จําเป็นในส่วนที่ผู้ใช้เลือกที่จะขยายเท่านั้น ซึ่งจะจํากัดการแชร์ทรัพยากรผ่านตัวเลือกของผู้ใช้

หน้าเว็บหลายหน้า

เมื่อออกแบบเพื่อให้สิทธิ์เพิ่มขึ้น ระบบจะใช้หน้าเว็บหลายหน้าเพื่อส่งคําขอเฉพาะขอบเขตที่จําเป็นในการโหลดหน้าเว็บ ซึ่งช่วยลดความซับซ้อนและต้องใช้การเรียกหลายครั้งเพื่อขอความยินยอมจากผู้ใช้และเรียกโทเค็นการเข้าถึง

แอปแบบหลายหน้า
หน้าเว็บ รหัส
หน้า 1 เอกสารสําหรับอ่าน
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/documents.readonly',
  });
  client.requestAccessToken();
          
หน้า 2 กิจกรรมที่กําลังจะมีขึ้น
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/calendar.readonly',
  });
  client.requestAccessToken();
          
หน้า 3 ภาพสไลด์
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
  });
  client.requestAccessToken();
          

แต่ละหน้าจะขอขอบเขตที่จําเป็นและขอโทเค็นเพื่อการเข้าถึงโดยการเรียกใช้ initTokenClient() และ requestAccessToken() ณ เวลาที่โหลด ในกรณีนี้ หน้าเว็บแต่ละหน้าจะใช้เพื่อแยกแยะฟังก์ชันการทํางานของผู้ใช้และทรัพยากรตามขอบเขตอย่างชัดเจน ในสถานการณ์จริง หน้าเว็บแต่ละหน้าอาจขอขอบเขตที่เกี่ยวข้องหลายๆ ขอบเขต

สิทธิ์โดยละเอียด

สิทธิ์แบบละเอียดจะจัดการในลักษณะเดียวกันในทุกสถานการณ์ หลังจาก requestAccessToken() เรียกใช้ฟังก์ชันเรียกกลับและโทเค็นเพื่อการเข้าถึงแล้ว ให้ตรวจสอบว่าผู้ใช้ได้อนุมัติขอบเขตที่ขอโดยใช้ hasGrantedAllScopes() หรือ hasGrantedAnyScope() เช่น

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly \
          https://www.googleapis.com/auth/documents.readonly \
          https://www.googleapis.com/auth/photoslibrary.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
          'https://www.googleapis.com/auth/photoslibrary.readonly')) {
        // Look at pictures
        ...
      }
      if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
          'https://www.googleapis.com/auth/calendar.readonly',
          'https://www.googleapis.com/auth/documents.readonly')) {
        // Meeting planning and review documents
        ...
      }
    }
  },
});

เงินสนับสนุนที่เคยได้รับก่อนหน้านี้จากเซสชันหรือคําขอก่อนหน้าจะรวมอยู่ในคําตอบด้วย บันทึกคํายินยอมของผู้ใช้จะยังคงอยู่ตามผู้ใช้และ รหัสไคลเอ็นต์ และจะยังอยู่ในการเรียกไปยัง initTokenClient() หรือ requestAccessToken() หลายครั้ง โดยค่าเริ่มต้น ผู้ใช้จําเป็นต้องให้ความยินยอมเฉพาะครั้งแรกที่ผู้ใช้เข้าชมเว็บไซต์และขอขอบเขตใหม่ แต่อาจขอทุกครั้งที่โหลดหน้าเว็บโดยใช้ prompt=consent ในออบเจ็กต์การกําหนดค่าไคลเอ็นต์โทเค็น

การทํางานกับโทเค็น

ในรูปแบบโทเค็น ระบบปฏิบัติการหรือเบราว์เซอร์จะไม่จัดเก็บโทเค็นเพื่อการเข้าถึง แต่จะได้รับโทเค็นใหม่ก่อนเมื่อโหลดหน้าเว็บ หรือหลังจากนั้นจะเรียกใช้ requestAccessToken() ผ่านท่าทางสัมผัสของผู้ใช้ เช่น การกดปุ่ม

การใช้ REST และ CORS กับ Google API

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

ในตัวอย่างนี้ ดูกิจกรรมในปฏิทินที่ลงชื่อเข้าใช้ของผู้ใช้ที่ลงชื่อเข้าใช้โดยใช้โทเค็นเพื่อการเข้าถึงที่ tokenRequest() แสดงผล

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();

ดูวิธีใช้ CORS เพื่อเข้าถึง Google API เพิ่มเติม

ส่วนถัดไปจะครอบคลุมวิธีผสานรวมกับ API ที่ซับซ้อนยิ่งขึ้นได้อย่างง่ายดาย

การทํางานกับไลบรารี JavaScript ของ Google APIs

ไคลเอ็นต์โทเค็นทํางานร่วมกับไลบรารีของไคลเอ็นต์ Google API สําหรับ JavaScript ดูข้อมูลโค้ดด้านล่าง

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  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(...);
}

การหมดอายุของโทเค็น

โทเค็นเพื่อการเข้าถึงมีอายุการใช้งานสั้นตามการออกแบบ หากโทเค็นเพื่อการเข้าถึงหมดอายุก่อนสิ้นสุดเซสชันของผู้ใช้ ให้ขอรับโทเค็นใหม่โดยเรียก requestAccessToken() จากเหตุการณ์ขับเคลื่อนของผู้ใช้ เช่น การกดปุ่ม

เรียกใช้เมธอด google.accounts.oauth2.revoke เพื่อนําคํายินยอมของผู้ใช้ออกและการเข้าถึง ทรัพยากรสําหรับขอบเขตทั้งหมดที่แอปของคุณได้รับ ต้องมีโทเค็นการเข้าถึงที่ถูกต้องเพื่อเพิกถอนสิทธิ์นี้

google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
    console.log(done);
    console.log(done.successful);
    console.log(done.error);
    console.log(done.error_description);
  });