google.accounts.oauth2ไลบรารี JavaScript ช่วยให้คุณขอความยินยอมจากผู้ใช้
และรับโทเค็นเพื่อการเข้าถึงเพื่อใช้กับข้อมูลผู้ใช้ได้ โดยอิงตามขั้นตอนการให้สิทธิ์โดยนัยของ OAuth 2.0 และออกแบบมาเพื่อให้คุณเรียกใช้ Google API ได้โดยตรงโดยใช้ REST และ CORS หรือใช้ไลบรารีของไคลเอ็นต์ Google APIs สำหรับ JavaScript (หรือที่เรียกว่า gapi.client) เพื่อเข้าถึง API ที่ซับซ้อนมากขึ้นได้อย่างยืดหยุ่น
ก่อนที่จะเข้าถึงข้อมูลผู้ใช้ที่ได้รับการปกป้องจากเบราว์เซอร์ ผู้ใช้ในเว็บไซต์ของคุณจะทริกเกอร์ ตัวเลือกบัญชีบนเว็บของ Google, กระบวนการลงชื่อเข้าใช้และความยินยอม และสุดท้าย เซิร์ฟเวอร์ OAuth ของ Google จะออกและส่งคืนโทเค็นเพื่อการเข้าถึงเว็บแอปของคุณ
ในรูปแบบการให้สิทธิ์ตามโทเค็น คุณไม่จำเป็นต้องจัดเก็บโทเค็นการรีเฟรชต่อผู้ใช้ ในเซิร์ฟเวอร์แบ็กเอนด์
เราขอแนะนำให้คุณทำตามแนวทางที่ระบุไว้ที่นี่แทนเทคนิคที่อธิบายไว้ในคำแนะนำOAuth 2.0 สำหรับเว็บแอปพลิเคชันฝั่งไคลเอ็นต์ฉบับเก่า
ข้อกำหนดเบื้องต้น
ทําตามขั้นตอนที่อธิบายไว้ในการตั้งค่าเพื่อกําหนดค่าหน้าจอขอความยินยอม OAuth รับรหัสไคลเอ็นต์ และโหลดไลบรารีของไคลเอ็นต์
เริ่มต้นไคลเอ็นต์โทเค็น
เรียกใช้ 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 ที่มีโทเค็นเพื่อการเข้าถึงและรายการขอบเขตที่ผู้ใช้ให้สิทธิ์เข้าถึง หรือข้อผิดพลาด ไปยัง Callback Handler ของคุณ
ผู้ใช้อาจปิดตัวเลือกบัญชีหรือหน้าต่างลงชื่อเข้าใช้ ในกรณีนี้ ระบบจะไม่เรียกใช้ฟังก์ชัน Callback ของคุณ
วิธีจัดการความยินยอม
คุณควรออกแบบและมอบประสบการณ์ของผู้ใช้สำหรับแอปหลังจากที่ได้อ่านนโยบาย OAuth 2.0 ของ Google อย่างละเอียดแล้วเท่านั้น นโยบายเหล่านี้ครอบคลุมถึง การทำงานกับขอบเขตหลายรายการ เวลาและวิธีจัดการความยินยอมของผู้ใช้ และอื่นๆ
การให้สิทธิ์แบบเพิ่มทีละรายการคือนโยบายและวิธีการออกแบบแอปที่ใช้เพื่อ ขอสิทธิ์เข้าถึงทรัพยากรโดยใช้ขอบเขตตามที่จำเป็นเท่านั้น แทนที่จะขอสิทธิ์ล่วงหน้า และขอทั้งหมดในครั้งเดียว ผู้ใช้อาจอนุมัติหรือปฏิเสธการแชร์ทรัพยากรแต่ละรายการ ที่แอปของคุณขอ ซึ่งเรียกว่าสิทธิ์แบบละเอียด
ในกระบวนการนี้ Google จะแจ้งให้ผู้ใช้ให้ความยินยอมของผู้ใช้ โดยแสดงขอบเขตที่ขอแต่ละรายการแยกกัน ผู้ใช้จะเลือกทรัพยากรที่จะแชร์กับแอปของคุณ และสุดท้าย Google จะเรียกใช้ฟังก์ชัน Callback เพื่อส่งคืนโทเค็นเพื่อการเข้าถึงและขอบเขตที่ผู้ใช้ อนุมัติ จากนั้นแอปจะจัดการผลลัพธ์ต่างๆ ที่อาจเกิดขึ้นได้อย่างปลอดภัย ด้วยสิทธิ์แบบละเอียด
แต่ก็มีข้อยกเว้น แอป Google Workspace Enterprise ที่มีการมอบสิทธิ์ระดับโดเมนหรือแอปที่ทำเครื่องหมายเป็นเชื่อถือได้ จะข้ามหน้าจอขอความยินยอมให้สิทธิ์แบบละเอียด สำหรับแอปเหล่านี้ ผู้ใช้จะไม่เห็นหน้าจอขอความยินยอมให้สิทธิ์แบบละเอียด แต่แอปของคุณจะได้รับ ขอบเขตที่ขอทั้งหมดหรือไม่ก็ไม่ได้รับเลย
ดูข้อมูลโดยละเอียดเพิ่มเติมได้ที่วิธีจัดการสิทธิ์แบบละเอียด
การให้สิทธิ์แบบเพิ่ม
สำหรับเว็บแอป สถานการณ์ระดับสูง 2 สถานการณ์ต่อไปนี้แสดงการให้สิทธิ์แบบค่อยเป็นค่อยไปโดยใช้
- แอป Ajax หน้าเว็บเดียวซึ่งมักใช้
XMLHttpRequestที่มีการเข้าถึงแบบไดนามิกไปยัง ทรัพยากร - หน้าเว็บหลายหน้า ทรัพยากรจะแยกกันและได้รับการจัดการตามหน้าเว็บ
สถานการณ์ทั้ง 2 นี้แสดงให้เห็นถึงข้อควรพิจารณาในการออกแบบและวิธีการต่างๆ แต่ไม่ได้มีวัตถุประสงค์เพื่อเป็นคำแนะนำที่ครอบคลุมเกี่ยวกับวิธีสร้างความยินยอมในแอป แอปในโลกแห่งความเป็นจริงอาจใช้เทคนิคเหล่านี้ในรูปแบบต่างๆ หรือใช้ร่วมกัน
อาแจ๊กซ์
เพิ่มการรองรับการให้สิทธิ์แบบเพิ่มทีละรายการลงในแอปโดยการเรียกใช้หลายครั้ง
ไปยัง requestAccessToken() และใช้พารามิเตอร์ scope ของออบเจ็กต์ OverridableTokenClientConfig
เพื่อขอขอบเขตแต่ละรายการในเวลาที่จำเป็นและ
เมื่อจำเป็นเท่านั้น ในตัวอย่างนี้ ระบบจะขอทรัพยากรและแสดงทรัพยากร
หลังจากที่ท่าทางผู้ใช้ขยายส่วนเนื้อหาที่ยุบไว้เท่านั้น
| แอป 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 แต่ละครั้งจะทริกเกอร์ช่วงเวลาที่ขอความยินยอมจากผู้ใช้ โดยแอปของคุณจะมีสิทธิ์เข้าถึงเฉพาะทรัพยากรที่ส่วนที่ผู้ใช้เลือกขยายกำหนดไว้เท่านั้น ซึ่งจะจำกัดการแชร์ทรัพยากรผ่านตัวเลือกของผู้ใช้
หน้าเว็บหลายหน้า
เมื่อออกแบบการให้สิทธิ์แบบเพิ่มทีละรายการ จะมีการใช้หลายหน้าเพื่อขอเฉพาะขอบเขตที่จำเป็นในการโหลดหน้าเว็บ ซึ่งจะช่วยลดความซับซ้อนและความจำเป็นในการเรียกหลายครั้งเพื่อขอรับความยินยอมของผู้ใช้และดึงโทเค็นเพื่อการเข้าถึง
| แอปแบบหลายหน้า | ||||||||
|---|---|---|---|---|---|---|---|---|
|
แต่ละหน้าจะขอขอบเขตที่จำเป็นและรับโทเค็นเพื่อการเข้าถึงโดยการเรียกใช้
initTokenClient() และ requestAccessToken() ในเวลาที่ใช้ในการโหลด ในสถานการณ์นี้
หน้าเว็บแต่ละหน้าจะใช้เพื่อแยกฟังก์ชันการทำงานของผู้ใช้และ
ทรัพยากรตามขอบเขตอย่างชัดเจน ในสถานการณ์จริง หน้าเว็บแต่ละหน้าอาจขอขอบเขตที่เกี่ยวข้องหลายรายการ
สิทธิ์แบบละเอียด
ระบบจะจัดการสิทธิ์แบบละเอียดในลักษณะเดียวกันในทุกสถานการณ์ หลังจากที่
requestAccessToken() เรียกใช้ฟังก์ชัน Callback และส่งคืนโทเค็นเพื่อการเข้าถึง
แล้ว ให้ตรวจสอบว่าผู้ใช้ได้อนุมัติขอบเขตที่ขอโดยใช้
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 APIs
คุณใช้โทเค็นเพื่อการเข้าถึงเพื่อส่งคำขอที่ผ่านการตรวจสอบสิทธิ์ไปยัง Google APIs ได้โดยใช้ 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();
Google API รองรับ CORS โดยค่าเริ่มต้น ซึ่งรวมถึงโทเค็นเพื่อการเข้าถึงในคำขอ XMLHttpRequest หรือ fetch จะทริกเกอร์การตรวจสอบ CORS ก่อนส่งคำขอจริง และคำขอ OPTIONS ก่อนคำขอ GET หรือ POST
ส่วนถัดไปจะอธิบายวิธีผสานรวมกับ 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);
});