OAuth 2.0 สําหรับเว็บแอปพลิเคชันฝั่งไคลเอ็นต์

จัดทุกอย่างให้เป็นระเบียบอยู่เสมอด้วยคอลเล็กชัน บันทึกและจัดหมวดหมู่เนื้อหาตามค่ากำหนดของคุณ

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

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

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

สิ่งที่ต้องดำเนินการก่อน

เปิดใช้ API สําหรับโปรเจ็กต์ของคุณ

แอปพลิเคชันที่เรียกใช้ Google API จะต้องเปิดใช้ API ดังกล่าวใน API Console

วิธีเปิดใช้ API สําหรับโปรเจ็กต์ของคุณ

  1. Open the API Library ใน Google API Console
  2. If prompted, select a project, or create a new one.
  3. API Library จะแสดง API ที่พร้อมใช้งานทั้งหมด โดยจัดกลุ่มตามครอบครัวและความนิยมของผลิตภัณฑ์ หาก API ที่ต้องการเปิดใช้ไม่แสดงในรายการ ให้ใช้การค้นหาเพื่อหาดังกล่าว หรือคลิกดูทั้งหมดในกลุ่มผลิตภัณฑ์ที่มี
  4. เลือก API ที่ต้องการเปิดใช้ แล้วคลิกปุ่มเปิดใช้
  5. If prompted, enable billing.
  6. If prompted, read and accept the API's Terms of Service.

สร้างข้อมูลเข้าสู่ระบบการให้สิทธิ์

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

  1. Go to the Credentials page.
  2. คลิกสร้างข้อมูลเข้าสู่ระบบ > รหัสไคลเอ็นต์ OAuth
  3. เลือกประเภทแอปพลิเคชันเว็บแอปพลิเคชัน
  4. กรอกข้อมูลในแบบฟอร์มให้ครบถ้วน แอปพลิเคชันที่ใช้ JavaScript ในการส่งคําขอ Google API ที่ได้รับอนุญาตต้องระบุต้นทาง JavaScript ที่ได้รับอนุญาต ต้นทางจะระบุโดเมนที่แอปพลิเคชันสามารถส่งคําขอไปยังเซิร์ฟเวอร์ OAuth 2.0 ได้ ต้นทางเหล่านี้ต้องเป็นไปตามกฎการตรวจสอบของ Google

ระบุขอบเขตการเข้าถึง

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

ก่อนที่จะเริ่มใช้การให้สิทธิ์ OAuth 2.0 เราขอแนะนําให้คุณระบุขอบเขตที่แอปจะต้องมีสิทธิ์เข้าถึง

เอกสารขอบเขต API ของ OAuth 2.0 ประกอบด้วยรายการขอบเขตทั้งหมดที่คุณอาจนําไปใช้เพื่อเข้าถึง Google API

การรับโทเค็นเพื่อการเข้าถึง OAuth 2.0

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

ขั้นตอนที่ 1: กําหนดค่าออบเจ็กต์ไคลเอ็นต์

หากใช้ไลบรารีของไคลเอ็นต์ Google API สําหรับ JavaScript เพื่อจัดการขั้นตอน OAuth 2.0 ขั้นตอนแรกให้กําหนดค่าออบเจ็กต์ gapi.auth2 และ gapi.client ออบเจ็กต์เหล่านี้ช่วยให้แอปพลิเคชันของคุณได้รับสิทธิ์จากผู้ใช้และส่งคําขอ API ที่ได้รับอนุญาตได้

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

ไลบรารีของไคลเอ็นต์ JS

ไลบรารีของไคลเอ็นต์ JavaScript ช่วยให้ขั้นตอนการให้สิทธิ์ในด้านต่างๆ ง่ายขึ้น ดังนี้

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

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

การเรียก gapi.client.init จะระบุช่องต่อไปนี้

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

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

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

หลังจากการเรียกใช้ gapi.client.init เสร็จสิ้นแล้ว โค้ดจะตั้งค่าตัวแปร GoogleAuth เพื่อระบุออบเจ็กต์ Google Auth สุดท้าย โค้ดจะตั้งค่า Listener ที่เรียกใช้ฟังก์ชันเมื่อสถานะการลงชื่อเข้าใช้ของผู้ใช้มีการเปลี่ยนแปลง (ไม่มีการกําหนดฟังก์ชันดังกล่าวในข้อมูลโค้ด)

var GoogleAuth; // Google Auth object.
function initClient() {
  gapi.client.init({
      'apiKey': 'YOUR_API_KEY',
      'clientId': 'YOUR_CLIENT_ID',
      'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
      'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/drive/v3/rest']
  }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);
  });
}

ปลายทาง OAuth 2.0

หากเข้าถึงปลายทาง OAuth 2.0 โดยตรง คุณจะไปยังขั้นตอนถัดไปได้

ขั้นตอนที่ 2: เปลี่ยนเส้นทางไปยังเซิร์ฟเวอร์ OAuth 2.0 ของ Google

หากต้องการขอสิทธิ์เข้าถึงข้อมูลของผู้ใช้ ให้เปลี่ยนเส้นทางผู้ใช้ไปยังเซิร์ฟเวอร์ OAuth 2.0 ของ Google

ไลบรารีของไคลเอ็นต์ JS

เรียกเมธอด GoogleAuth.signIn() เพื่อนําผู้ใช้ไปยังเซิร์ฟเวอร์การให้สิทธิ์ของ Google

GoogleAuth.signIn();

ในทางปฏิบัติ แอปพลิเคชันของคุณอาจตั้งค่าบูลีนเพื่อระบุว่าจะเรียกเมธอด signIn() หรือไม่ก่อนที่จะพยายามเรียก API

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

  • ออบเจ็กต์ GoogleAuth ที่อ้างอิงในโค้ดเหมือนกับตัวแปรร่วมที่กําหนดไว้ในข้อมูลโค้ดในขั้นตอนที่ 1

  • ฟังก์ชัน updateSigninStatus คือ Listener ที่ฟังการเปลี่ยนแปลงสถานะการให้สิทธิ์ของผู้ใช้ นอกจากนี้ ยังกําหนดบทบาทของ Listener เป็นผู้ฟังในข้อมูลโค้ดในขั้นตอนที่ 1 ดังต่อไปนี้
    GoogleAuth.isSignedIn.listen(updateSigninStatus);
  • ข้อมูลโค้ดจะกําหนดตัวแปรร่วมเพิ่มเติม 2 รายการ ดังนี้

    • isAuthorized เป็นตัวแปรบูลีนที่ระบุว่าผู้ใช้ลงชื่อเข้าใช้อยู่แล้วหรือไม่ คุณจะตั้งค่านี้ได้เมื่อแอปโหลดและอัปเดตหากผู้ใช้ลงชื่อเข้าใช้หรือออกจากระบบแอป

      ในตัวอย่างนี้ ฟังก์ชัน sendAuthorizedApiRequest จะตรวจสอบค่าของตัวแปรเพื่อดูว่าแอปควรพยายามส่งคําขอ API ที่ต้องมีการให้สิทธิ์หรือแจ้งให้ผู้ใช้ให้สิทธิ์แอปหรือไม่

    • currentApiRequest เป็นออบเจ็กต์ที่เก็บรายละเอียดเกี่ยวกับคําขอ API ล่าสุดที่ผู้ใช้พยายามทํา ระบบจะตั้งค่าของออบเจ็กต์เมื่อแอปเรียกใช้ฟังก์ชัน sendAuthorizedApiRequest

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

var isAuthorized;
var currentApiRequest;

/**
 * Store the request details. Then check to determine whether the user
 * has authorized the application.
 *   - If the user has granted access, make the API request.
 *   - If the user has not granted access, initiate the sign-in flow.
 */
function sendAuthorizedApiRequest(requestDetails) {
  currentApiRequest = requestDetails;
  if (isAuthorized) {
    // Make API request
    // gapi.client.request(requestDetails)

    // Reset currentApiRequest variable.
    currentApiRequest = {};
  } else {
    GoogleAuth.signIn();
  }
}

/**
 * Listener called when user completes auth flow. If the currentApiRequest
 * variable is set, then the user was prompted to authorize the application
 * before the request executed. In that case, proceed with that API request.
 */
function updateSigninStatus(isSignedIn) {
  if (isSignedIn) {
    isAuthorized = true;
    if (currentApiRequest) {
      sendAuthorizedApiRequest(currentApiRequest);
    }
  } else {
    isAuthorized = false;
  }
}

ปลายทาง OAuth 2.0

สร้าง URL เพื่อขอสิทธิ์เข้าถึงจากปลายทาง OAuth 2.0 ของ Google ที่ https://accounts.google.com/o/oauth2/v2/auth ปลายทางนี้เข้าถึงผ่าน HTTPS ได้ ปฏิเสธการเชื่อมต่อ HTTP ธรรมดา

เซิร์ฟเวอร์การให้สิทธิ์ของ Google รองรับพารามิเตอร์สตริงการค้นหาต่อไปนี้สําหรับแอปพลิเคชันเว็บเซิร์ฟเวอร์

พารามิเตอร์
client_id จำเป็น

รหัสไคลเอ็นต์สําหรับแอปพลิเคชัน คุณดูค่านี้ได้ใน API Console Credentials page

redirect_uri จำเป็น

กําหนดตําแหน่งที่เซิร์ฟเวอร์ API เปลี่ยนเส้นทางผู้ใช้หลังจากที่ผู้ใช้ดําเนินการขั้นตอนการให้สิทธิ์เรียบร้อยแล้ว ค่าต้องตรงกับ URI การเปลี่ยนเส้นทางที่ได้รับอนุญาตรายการใดรายการหนึ่งสําหรับไคลเอ็นต์ OAuth 2.0 ซึ่งคุณกําหนดค่าไว้ใน API Console Credentials pageของไคลเอ็นต์ หากค่านี้ไม่ตรงกับ URI การเปลี่ยนเส้นทางที่ได้รับอนุญาตสําหรับ client_id ที่ระบุ คุณจะได้รับข้อผิดพลาด redirect_uri_mismatch

โปรดทราบว่ารูปแบบ http หรือ https, เคส และเครื่องหมายทับปิดท้าย ("/") ต้องตรงกันทั้งหมด

response_type จำเป็น

แอปพลิเคชัน JavaScript ต้องตั้งค่าค่าของพารามิเตอร์เป็น token ค่านี้จะสั่งให้เซิร์ฟเวอร์การให้สิทธิ์ของ Google แสดงผลโทเค็นเพื่อการเข้าถึงเป็นคู่ของ name=value ในตัวระบุส่วนย่อยของ URI (#) ที่มีการเปลี่ยนเส้นทางผู้ใช้หลังจากเสร็จสิ้นกระบวนการให้สิทธิ์

scope จำเป็น

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

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

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

state แนะนำ

ระบุค่าสตริงที่แอปพลิเคชันใช้เพื่อรักษาสถานะระหว่างคําขอการให้สิทธิ์กับการตอบสนองของเซิร์ฟเวอร์การให้สิทธิ์ เซิร์ฟเวอร์จะแสดงค่าที่แน่นอนที่คุณส่งเป็นคู่ของ name=value ในตัวระบุส่วนย่อยของ URL (#) ของ redirect_uri หลังจากที่ผู้ใช้ให้ความยินยอมหรือปฏิเสธคําขอการเข้าถึงของแอปพลิเคชัน

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

include_granted_scopes ไม่บังคับ

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

login_hint ไม่บังคับ

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

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

prompt ไม่บังคับ

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

โดยค่าที่เป็นไปได้มีดังนี้

none อย่าแสดงหน้าจอการตรวจสอบสิทธิ์หรือความยินยอม ต้องระบุด้วยค่าอื่น
consent แสดงข้อความแจ้งผู้ใช้เพื่อขอความยินยอม
select_account แสดงข้อความแจ้งให้ผู้ใช้เลือกบัญชี

ตัวอย่างการเปลี่ยนเส้นทางไปยังเซิร์ฟเวอร์การให้สิทธิ์ของ Google

URL ตัวอย่างจะแสดงด้านล่างโดยมีตัวแบ่งบรรทัดและช่องว่างเพื่อให้อ่านได้

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

หลังจากสร้าง URL คําขอแล้ว ให้เปลี่ยนเส้นทางผู้ใช้ไปยัง URL นั้น

โค้ดตัวอย่าง JavaScript

ข้อมูลโค้ด JavaScript ต่อไปนี้แสดงวิธีเริ่มขั้นตอนการให้สิทธิ์ใน JavaScript โดยไม่ต้องใช้ไลบรารีของไคลเอ็นต์ Google API สําหรับ JavaScript เนื่องจากปลายทาง OAuth 2.0 นี้ไม่รองรับการแชร์ทรัพยากรข้ามโดเมน (CORS) ข้อมูลโค้ดจึงสร้างแบบฟอร์มที่เปิดคําขอไปยังปลายทางนั้น

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

ขั้นตอนที่ 3: Google แสดงข้อความแจ้งผู้ใช้เพื่อขอความยินยอม

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

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

ข้อผิดพลาด

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

admin_policy_enforced

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

disallowed_useragent

ปลายทางการให้สิทธิ์จะแสดงภายใน User Agent ที่ฝังซึ่งนโยบาย OAuth 2.0 ของ Google ไม่อนุญาต

Android

นักพัฒนาแอป Android อาจพบข้อความแสดงข้อผิดพลาดนี้เมื่อเปิดคําขอการให้สิทธิ์ใน android.webkit.WebView นักพัฒนาซอฟต์แวร์ควรใช้ไลบรารี Android เช่น Google Sign-In สําหรับ Android หรือ AppAuth สําหรับ Android ของ OpenID Foundation

นักพัฒนาเว็บอาจพบข้อผิดพลาดนี้เมื่อแอป Android เปิดลิงก์เว็บทั่วไปใน User Agent แบบฝัง และผู้ใช้ไปยังปลายทางการให้สิทธิ์ OAuth 2.0 ของ Google จากเว็บไซต์ของคุณ นักพัฒนาซอฟต์แวร์ควรเปิดลิงก์ทั่วไปในเครื่องจัดการลิงก์เริ่มต้นของระบบปฏิบัติการ ซึ่งมีทั้งเครื่องจัดการ Android App Link หรือแอปเบราว์เซอร์เริ่มต้น ไลบรารีแท็บที่กําหนดเองของ Android ก็เป็นตัวเลือกที่รองรับเช่นกัน

iOS

นักพัฒนาแอป iOS และ macOS อาจพบข้อผิดพลาดนี้เมื่อเปิดคําขอการให้สิทธิ์ใน WKWebView นักพัฒนาซอฟต์แวร์ควรใช้ไลบรารี iOS เช่น Google Sign-In สําหรับ iOS หรือ AppAuth สําหรับ iOS ของ OpenID Foundation

นักพัฒนาเว็บอาจพบข้อผิดพลาดนี้เมื่อแอป iOS หรือ macOS เปิดลิงก์เว็บทั่วไปใน User Agent ที่ฝัง และผู้ใช้ไปยังปลายทางการให้สิทธิ์ OAuth 2.0 ของ Google จากเว็บไซต์ของคุณ นักพัฒนาซอฟต์แวร์ควรอนุญาตให้ลิงก์ทั่วไปเปิดในเครื่องจัดการลิงก์เริ่มต้นของระบบปฏิบัติการ ซึ่งมีทั้งเครื่องจัดการ Universal Link หรือแอปเบราว์เซอร์เริ่มต้น และไลบรารี SFSafariViewController ก็เป็นตัวเลือกที่รองรับเช่นกัน

org_internal

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

invalid_client

ต้นทางที่สร้างคําขอไม่ได้รับอนุญาตสําหรับไคลเอ็นต์นี้ ดู origin_mismatch

invalid_grant

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

origin_mismatch

สคีม โดเมน และ/หรือพอร์ตของ JavaScript ที่มาจากคําขอการให้สิทธิ์อาจไม่ตรงกับ URI ต้นทางของ JavaScript ที่ได้รับอนุญาตที่ลงทะเบียนสําหรับรหัสไคลเอ็นต์ OAuth ตรวจสอบต้นทาง JavaScript ที่ได้รับอนุญาตใน Google API Console Credentials page

redirect_uri_mismatch

redirect_uri ที่ส่งผ่านในคําขอการให้สิทธิ์ไม่ตรงกับ URI การเปลี่ยนเส้นทางที่ได้รับอนุญาตสําหรับรหัสไคลเอ็นต์ OAuth ตรวจสอบ URI การเปลี่ยนเส้นทางที่ได้รับอนุญาตใน Google API Console Credentials page

สคีม โดเมน และ/หรือพอร์ตของ JavaScript ที่มาจากคําขอการให้สิทธิ์อาจไม่ตรงกับ URI ต้นทางของ JavaScript ที่ได้รับอนุญาตที่ลงทะเบียนสําหรับรหัสไคลเอ็นต์ OAuth ตรวจสอบต้นทาง JavaScript ที่ได้รับอนุญาตใน Google API Console Credentials page

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

ขั้นตอนที่ 4: จัดการการตอบกลับของเซิร์ฟเวอร์ OAuth 2.0

ไลบรารีของไคลเอ็นต์ JS

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

ปลายทาง OAuth 2.0

เซิร์ฟเวอร์ OAuth 2.0 จะส่งการตอบกลับไปยัง redirect_uri ที่ระบุในคําขอโทเค็นเพื่อการเข้าถึง

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

  • การตอบกลับโทเค็นเพื่อการเข้าถึงมีดังนี้

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

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

  • การตอบกลับข้อผิดพลาด
    https://oauth2.example.com/callback#error=access_denied

ตัวอย่างการตอบกลับของเซิร์ฟเวอร์ OAuth 2.0

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

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly&
 include_granted_scopes=true&
 response_type=token&
 state=state_parameter_passthrough_value&
 redirect_uri=https%3A//oauth2.example.com/code&
 client_id=client_id

หลังจากเสร็จสิ้นขั้นตอน OAuth 2.0 แล้ว ระบบจะเปลี่ยนเส้นทางของคุณไปยัง http://localhost/oauth2callback URL นั้นจะทําให้เกิดข้อผิดพลาด 404 NOT FOUND เว้นแต่ว่าเครื่องภายในจะแสดงในไฟล์ที่ที่อยู่นั้น ขั้นตอนถัดไปจะแสดงรายละเอียดเพิ่มเติมเกี่ยวกับข้อมูลที่แสดงผลใน URI เมื่อผู้ใช้เปลี่ยนเส้นทางกลับไปยังแอปพลิเคชันของคุณ

การเรียกใช้ Google API

ไลบรารีของไคลเอ็นต์ JS

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

ไลบรารีของไคลเอ็นต์รองรับ 2 วิธีในการเรียกใช้เมธอด API หากคุณโหลดเอกสารการค้นพบแล้ว API จะกําหนดฟังก์ชันเฉพาะเมธอดให้คุณ คุณยังใช้ฟังก์ชัน gapi.client.request เพื่อเรียกเมธอด API ได้ด้วย ข้อมูลโค้ด 2 รายการต่อไปนี้แสดงตัวเลือกเหล่านี้สําหรับเมธอด about.get ของ Drive API

// Example 1: Use method-specific function
var request = gapi.client.drive.about.get({'fields': 'user'});

// Execute the API request.
request.execute(function(response) {
  console.log(response);
});


// Example 2: Use gapi.client.request(args) function
var request = gapi.client.request({
  'method': 'GET',
  'path': '/drive/v3/about',
  'params': {'fields': 'user'}
});
// Execute the API request.
request.execute(function(response) {
  console.log(response);
});

ปลายทาง OAuth 2.0

หลังจากที่แอปพลิเคชันได้รับโทเค็นเพื่อการเข้าถึง คุณจะใช้โทเค็นเพื่อเรียก API ของ Google ในนามของบัญชีผู้ใช้ดังกล่าวได้ หากขอบเขตการเข้าถึงที่ API กําหนดไว้นั้นได้รับอนุญาต โดยใส่โทเค็นเพื่อการเข้าถึงในคําขอลงใน API ด้วยการใส่พารามิเตอร์การค้นหา access_token หรือค่า Authorization ของส่วนหัว HTTP เป็น Bearer หากเป็นไปได้ ส่วนหัว HTTP เป็นตัวเลือกที่ดีกว่า เนื่องจากสตริงการค้นหามีแนวโน้มที่จะแสดงในบันทึกของเซิร์ฟเวอร์ ในกรณีส่วนใหญ่ คุณสามารถใช้ไลบรารีของไคลเอ็นต์เพื่อตั้งค่าการเรียกไปยัง Google API (เช่น เมื่อเรียก Drive Files API)

คุณจะลองใช้ Google API ทั้งหมดและดูขอบเขตได้ที่ OAuth 2.0 Playground

ตัวอย่าง HTTP GET

การเรียกปลายทาง drive.files (Drive Files API) โดยใช้ส่วนหัว HTTP ของ Authorization: Bearer อาจมีลักษณะดังต่อไปนี้ โปรดทราบว่าคุณต้องระบุโทเค็นเพื่อการเข้าถึงของคุณเอง ดังนี้

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

นี่คือการเรียกไปยัง API เดียวกันสําหรับผู้ใช้ที่ตรวจสอบสิทธิ์โดยใช้พารามิเตอร์สตริงการค้นหา access_token

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

ตัวอย่างของ curl

คุณทดสอบคําสั่งเหล่านี้ได้โดยใช้แอปพลิเคชันบรรทัดคําสั่ง curl ตัวอย่างที่ใช้ตัวเลือกส่วนหัวของ HTTP (แนะนํา) มีดังนี้

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

หรือเลือกตัวเลือกพารามิเตอร์สตริงการค้นหา ดังนี้

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

โค้ดตัวอย่าง JavaScript

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

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

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/drive/v3/about?fields=user&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

ตัวอย่างที่สมบูรณ์

ไลบรารีของไคลเอ็นต์ JS

การสาธิตโค้ดตัวอย่าง

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

โปรดทราบว่าแอปนี้ขอสิทธิ์เข้าถึงขอบเขต https://www.googleapis.com/auth/drive.metadata.readonly มีการขอสิทธิ์การเข้าถึงเพื่อสาธิตวิธีการเริ่มขั้นตอน OAuth 2.0 ในแอปพลิเคชัน JavaScript เท่านั้น แอปนี้ไม่ได้ส่งคําขอ API

โค้ดตัวอย่าง JavaScript

ดังที่แสดงด้านบน ตัวอย่างโค้ดนี้มีไว้สําหรับหน้าเว็บ (แอป) ที่โหลดไลบรารีของไคลเอ็นต์ Google API สําหรับ JavaScript และเริ่มขั้นตอน OAuth 2.0 หน้าเว็บจะแสดงข้อมูลอย่างใดอย่างหนึ่งต่อไปนี้

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

คุณยังเพิกถอนสิทธิ์เข้าถึงแอปผ่านหน้าสิทธิ์ของบัญชี Google ได้ด้วย แอปนี้จะแสดงเป็นการสาธิต OAuth 2.0 สําหรับ Google API เอกสาร

<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

ปลายทาง OAuth 2.0

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

สําหรับขั้นตอน OAuth 2.0 หน้าเว็บจะทําตามขั้นตอนต่อไปนี้

  1. ซึ่งจะนําผู้ใช้ไปยังเซิร์ฟเวอร์ OAuth 2.0 ของ Google ซึ่งขอสิทธิ์เข้าถึงขอบเขต https://www.googleapis.com/auth/drive.metadata.readonly
  2. หลังจากให้สิทธิ์ (หรือปฏิเสธ) เข้าถึงขอบเขตที่ขออย่างน้อย 1 รายการ ระบบจะเปลี่ยนเส้นทางผู้ใช้ไปยังหน้าต้นฉบับ ซึ่งจะแยกวิเคราะห์โทเค็นเพื่อการเข้าถึงจากสตริงตัวระบุส่วนย่อย
  3. หน้าเว็บใช้โทเค็นเพื่อการเข้าถึงเพื่อสร้างคําขอ API ตัวอย่าง

    คําขอ API จะเรียกเมธอด about.get ของ Drive API เพื่อดึงข้อมูลเกี่ยวกับบัญชี Google ไดรฟ์ของผู้ใช้ที่ได้รับอนุญาต

  4. หากดําเนินการคําขอสําเร็จ ระบบจะบันทึกการตอบกลับ API ในคอนโซลการแก้ไขข้อบกพร่องของเบราว์เซอร์

คุณเพิกถอนสิทธิ์เข้าถึงแอปได้ผ่านหน้าสิทธิ์ของบัญชี Google แอปจะแสดงเป็นการสาธิต OAuth 2.0 สําหรับ Google API เอกสาร

หากต้องการเรียกใช้โค้ดในเครื่อง คุณต้องตั้งค่าสําหรับตัวแปร YOUR_CLIENT_ID และ YOUR_REDIRECT_URI ที่สอดคล้องกับข้อมูลเข้าสู่ระบบการให้สิทธิ์ ควรตั้งค่าตัวแปร YOUR_REDIRECT_URI เป็น URL เดียวกับที่แสดงหน้าเว็บ ค่านี้ต้องตรงกันทุกประการกับ URI การเปลี่ยนเส้นทางที่ได้รับอนุญาตสําหรับไคลเอ็นต์ OAuth 2.0 ซึ่งคุณกําหนดค่าไว้ใน API Console Credentials pageหากค่านี้ไม่ตรงกับ URI ที่ได้รับอนุญาต คุณจะได้รับข้อผิดพลาด redirect_uri_mismatch โปรเจ็กต์ของคุณต้องเปิดใช้ API ที่เหมาะสมสําหรับคําขอนี้

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

กฎการตรวจสอบต้นทางของ JavaScript

Google ใช้กฎการตรวจสอบต่อไปนี้กับต้นทางของ JavaScript เพื่อช่วยให้นักพัฒนาซอฟต์แวร์รักษาแอปพลิเคชันของตนให้ปลอดภัย ต้นทาง JavaScript ต้องเป็นไปตามกฎเหล่านี้ โปรดดูคําจํากัดความของโดเมน โฮสต์ และชุดรูปแบบที่ RFC 3986 ส่วน 3

กฎการตรวจสอบความถูกต้อง
รูปแบบ

ต้นทาง JavaScript ต้องใช้รูปแบบ HTTPS ไม่ใช่ HTTP ธรรมดา กฎ URI ของ Localhost (รวมถึง URI ของที่อยู่ IP ของ localhost) จะได้รับการยกเว้นจากกฎนี้

โฮสต์

โฮสต์ต้องไม่ใช่ที่อยู่ IP ดิบ กฎนี้ได้รับการยกเว้นจากที่อยู่ IP ของ Localhost

โดเมน
  • TLD โฮสต์ (โดเมนระดับบนสุด) ต้องเป็นของรายการคําต่อท้ายสาธารณะ
  • โดเมนโฮสต์ต้องไม่ใช่ “googleusercontent.com”
  • ต้นทาง JavaScript ต้องไม่มีโดเมนย่อ URL (เช่น goo.gl) เว้นแต่ว่าแอปเป็นเจ้าของโดเมน
  • ข้อมูลผู้ใช้

    ต้นทาง JavaScript ต้องไม่มีคอมโพเนนต์ย่อยของ userinfo

    เส้นทาง

    ต้นทาง JavaScript ต้องไม่มีคอมโพเนนต์เส้นทาง

    การค้นหา

    ต้นทาง JavaScript ต้องไม่มีคอมโพเนนต์การค้นหา

    ส่วนย่อย

    ต้นทาง JavaScript ต้องไม่มีคอมโพเนนต์ส่วนย่อย

    อักขระ ต้นทาง JavaScript ต้องไม่มีอักขระบางตัวต่อไปนี้
    • อักขระไวลด์การ์ด ('*')
    • อักขระ ASCII ที่พิมพ์ไม่ได้
    • การเข้ารหัสเปอร์เซ็นต์ไม่ถูกต้อง (การเข้ารหัสเปอร์เซ็นต์ที่ไม่เป็นไปตามรูปแบบการเข้ารหัส URL ของเครื่องหมายเปอร์เซ็นต์ตามด้วยเลขฐานสิบหก 2 หลัก)
    • อักขระ Null (อักขระ NULL ที่เข้ารหัส เช่น %00, %C0%80)

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

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

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

    ในกรณีนี้ แอปอาจขอขอบเขต openid และ profile ในการลงชื่อเข้าใช้แบบพื้นฐาน และจะขอขอบเขต https://www.googleapis.com/auth/drive.file ในขณะที่ขอบันทึกมิกซ์ครั้งแรก

    กฎต่อไปนี้ใช้กับโทเค็นเพื่อการเข้าถึงที่ได้รับจากการให้สิทธิ์เพิ่มเติม

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

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

    ไลบรารีของไคลเอ็นต์ JS

    หากต้องการเพิ่มขอบเขตในโทเค็นเพื่อการเข้าถึงที่มีอยู่ ให้เรียกใช้เมธอด GoogleUser.grant(options) ออบเจ็กต์ options ระบุขอบเขตเพิ่มเติมที่คุณต้องการให้สิทธิ์เข้าถึง

    // Space-separated list of additional scope(s) you are requesting access to.
    // This code adds read-only access to the user's calendars via the Calendar API.
    var NEW_SCOPES = 'https://www.googleapis.com/auth/calendar.readonly';
    
    // Retrieve the GoogleUser object for the current user.
    var GoogleUser = GoogleAuth.currentUser.get();
    GoogleUser.grant({'scope': NEW_SCOPES});

    ปลายทาง OAuth 2.0

    หากต้องการเพิ่มขอบเขตลงในโทเค็นเพื่อการเข้าถึงที่มีอยู่ ให้ใส่พารามิเตอร์ include_granted_scopes ในคําขอไปยังเซิร์ฟเวอร์ OAuth 2.0 ของ Google

    ข้อมูลโค้ดต่อไปนี้สาธิตวิธีการตรวจสอบ ข้อมูลโค้ดจะถือว่าคุณจัดเก็บขอบเขตที่โทเค็นเพื่อการเข้าถึงใช้งานได้ในพื้นที่เก็บข้อมูลของเบราว์เซอร์ (โค้ดตัวอย่างที่สมบูรณ์จะจัดเก็บรายการขอบเขตที่โทเค็นเพื่อการเข้าถึงถูกต้อง โดยการตั้งค่าพร็อพเพอร์ตี้ oauth2-test-params.scope ในพื้นที่เก็บข้อมูลของเบราว์เซอร์)

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

    var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    การเพิกถอนโทเค็น

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

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

    ไลบรารีของไคลเอ็นต์ JS

    หากต้องการเพิกถอนโทเค็นแบบเป็นโปรแกรม โปรดเรียกใช้ GoogleAuth.disconnect():

    GoogleAuth.disconnect();

    ปลายทาง OAuth 2.0

    หากต้องการเพิกถอนโทเค็นแบบเป็นโปรแกรม แอปพลิเคชันจะส่งคําขอไปยัง https://oauth2.googleapis.com/revoke และมีโทเค็นเป็นพารามิเตอร์ ดังนี้

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    ซึ่งจะเป็นโทเค็นเพื่อการเข้าถึงหรือโทเค็นการรีเฟรชก็ได้ หากโทเค็นเป็นโทเค็นเพื่อการเข้าถึงและมีโทเค็นการรีเฟรชที่เกี่ยวข้อง ระบบจะเพิกถอนโทเค็นการรีเฟรชด้วย

    เมื่อดําเนินการเพิกถอนเรียบร้อยแล้ว รหัสสถานะ HTTP ของการตอบกลับจะเป็น 200 สําหรับเงื่อนไขข้อผิดพลาด รหัสสถานะ HTTP 400 จะแสดงผลพร้อมกับรหัสข้อผิดพลาด

    ข้อมูลโค้ด JavaScript ต่อไปนี้แสดงวิธีเพิกถอนโทเค็นใน JavaScript โดยไม่ต้องใช้ไลบรารีของไคลเอ็นต์ Google API สําหรับ JavaScript เนื่องจากปลายทาง OAuth 2.0 ของ Google สําหรับการเพิกถอนโทเค็นไม่รองรับการแชร์ทรัพยากรแบบข้ามต้นทาง (CORS) โค้ดจึงสร้างแบบฟอร์มและส่งแบบฟอร์มไปยังปลายทางแทนการใช้เมธอด XMLHttpRequest() เพื่อโพสต์คําขอ

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }