การใช้ OAuth 2.0 สำหรับแอปพลิเคชันเว็บเซิร์ฟเวอร์

เอกสารนี้อธิบายวิธีที่แอปพลิเคชันเว็บเซิร์ฟเวอร์ใช้ไลบรารีของไคลเอ็นต์ Google API หรือปลายทาง OAuth 2.0 ของ Google เพื่อใช้การให้สิทธิ์ OAuth 2.0 เพื่อเข้าถึง YouTube Data API

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

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

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

YouTube Live Streaming API ไม่รองรับขั้นตอนสำหรับบัญชีบริการ เนื่องจากไม่สามารถลิงก์บัญชีบริการกับบัญชี YouTube ได้ การพยายามให้สิทธิ์คำขอด้วยขั้นตอนนี้จะทำให้เกิดข้อผิดพลาด NoLinkedYouTubeAccount

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

ตัวอย่างเฉพาะภาษาในหน้านี้ใช้ไลบรารีของไคลเอ็นต์ Google API เพื่อใช้การให้สิทธิ์ OAuth 2.0 หากต้องการเรียกใช้ตัวอย่างโค้ด คุณต้องติดตั้งไลบรารีไคลเอ็นต์สำหรับภาษาของคุณก่อน

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

ไลบรารีของไคลเอ็นต์ 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. ใช้หน้าไลบรารีเพื่อค้นหาและเปิดใช้ YouTube Data API ค้นหา API อื่นๆ ที่แอปพลิเคชันของคุณจะใช้และเปิดใช้ API เหล่านั้นด้วย

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

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

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

    สำหรับการทดสอบ คุณสามารถระบุ URI ที่อ้างอิงถึงเครื่องในเครื่อง เช่น http://localhost:8080 โปรดทราบว่าตัวอย่างทั้งหมดในเอกสารนี้ใช้ http://localhost:8080 เป็น URI การเปลี่ยนเส้นทาง

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

หลังจากสร้างข้อมูลเข้าสู่ระบบแล้ว ให้ดาวน์โหลดไฟล์ client_secret.json จาก API Consoleเก็บไฟล์อย่างปลอดภัยในตำแหน่งที่มีเพียงแอปพลิเคชันของคุณเท่านั้นที่เข้าถึงได้

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

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

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

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

YouTube Data API เวอร์ชัน 3 ใช้ขอบเขตต่อไปนี้

กล้องติดปืน
https://www.googleapis.com/auth/youtubeจัดการบัญชี YouTube ของคุณ
https://www.googleapis.com/auth/youtube.channel-memberships.creatorดูรายชื่อสมาชิกปัจจุบันที่ใช้งานอยู่ในช่องของคุณ ระดับปัจจุบันของสมาชิก และวันที่เริ่มเป็นสมาชิก
https://www.googleapis.com/auth/youtube.force-sslดู แก้ไข และลบวิดีโอ YouTube การจัดประเภท ความคิดเห็น และคำบรรยายวิดีโออย่างถาวร
https://www.googleapis.com/auth/youtube.readonlyดูบัญชี YouTube ของคุณ
https://www.googleapis.com/auth/youtube.uploadจัดการวิดีโอ YouTube ของคุณ
https://www.googleapis.com/auth/youtubepartnerดูและจัดการพื้นที่ของคุณและเนื้อหาที่เกี่ยวข้องใน YouTube
https://www.googleapis.com/auth/youtubepartner-channel-auditดูข้อมูลส่วนตัวของช่อง YouTube ของคุณที่เกี่ยวข้องในระหว่างกระบวนการตรวจสอบกับพาร์ทเนอร์ YouTube

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

ข้อกำหนดเฉพาะภาษา

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

PHP

หากต้องการเรียกใช้ตัวอย่างโค้ด PHP ในเอกสารนี้ คุณจะต้องมีสิ่งต่อไปนี้

  • PHP 8.0 ขึ้นไปที่ติดตั้งอินเทอร์เฟซบรรทัดคำสั่ง (CLI) และส่วนขยาย JSON
  • เครื่องมือการจัดการทรัพยากรของ Composer
  • ไลบรารีของไคลเอ็นต์ Google APIs สำหรับ PHP

    composer require google/apiclient:^2.15.0

ดูข้อมูลเพิ่มเติมได้ที่ไลบรารีของไคลเอ็นต์ Google APIs สำหรับ PHP

Python

หากต้องการเรียกใช้ตัวอย่างโค้ด Python ในเอกสารนี้ คุณจะต้องมีสิ่งต่อไปนี้

  • Python 3.7 ขึ้นไป
  • เครื่องมือจัดการแพ็กเกจ pip
  • ไลบรารีของไคลเอ็นต์ Google APIs สำหรับ Python เวอร์ชัน 2.0
    pip install --upgrade google-api-python-client
  • google-auth, google-auth-oauthlib และ google-auth-httplib2 สำหรับการให้สิทธิ์ผู้ใช้
    pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
  • เฟรมเวิร์กเว็บแอปพลิเคชัน Flask Python
    pip install --upgrade flask
  • ไลบรารี HTTP ของ requests
    pip install --upgrade requests

โปรดอ่านหมายเหตุเกี่ยวกับรุ่นของไลบรารีของไคลเอ็นต์ Google API สำหรับ Python หากอัปเกรด Python และคู่มือการย้ายข้อมูลที่เกี่ยวข้องไม่ได้

Ruby

หากต้องการเรียกใช้ตัวอย่างโค้ด Ruby ในเอกสารนี้ คุณจะต้องมีสิ่งต่อไปนี้

  • Ruby 2.6 ขึ้นไป
  • ไลบรารีการตรวจสอบสิทธิ์ของ Google สำหรับ Ruby

    gem install googleauth
  • ไลบรารีของไคลเอ็นต์สำหรับ Google API ของไดรฟ์และปฏิทิน

    gem install google-apis-drive_v3 google-apis-calendar_v3
  • เฟรมเวิร์กเว็บแอปพลิเคชัน Ruby ของ Sinatra

    gem install sinatra

Node.js

หากต้องการเรียกใช้ตัวอย่างโค้ด Node.js ในเอกสารนี้ คุณจะต้องมีสิ่งต่อไปนี้

  • LTS เวอร์ชันที่ใช้งานอยู่ LTS เวอร์ชันที่ดูแลรักษา หรือ Node.js เวอร์ชันปัจจุบัน
  • ไคลเอ็นต์ Node.js ของ Google APIs

    npm install googleapis crypto express express-session

HTTP/REST

คุณไม่จำเป็นต้องติดตั้งไลบรารีใดๆ เพื่อเรียกใช้ปลายทาง OAuth 2.0 โดยตรง

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

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

รายการด้านล่างสรุปขั้นตอนเหล่านี้อย่างรวดเร็ว

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

ขั้นตอนที่ 1: ตั้งค่าพารามิเตอร์การให้สิทธิ์

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

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

แท็บด้านล่างจะกำหนดพารามิเตอร์การให้สิทธิ์ที่รองรับสำหรับแอปพลิเคชันเว็บเซิร์ฟเวอร์ ตัวอย่างเฉพาะภาษายังแสดงวิธีใช้ไลบรารีไคลเอ็นต์หรือไลบรารีการให้สิทธิ์เพื่อกำหนดค่าออบเจ็กต์ที่ตั้งค่าพารามิเตอร์เหล่านั้นด้วย

PHP

ข้อมูลโค้ดต่อไปนี้สร้างออบเจ็กต์ Google\Client() ซึ่งกําหนดพารามิเตอร์ในคําขอการให้สิทธิ์

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

ตัวอย่างเช่น หากต้องการขอสิทธิ์เข้าถึงแบบออฟไลน์เพื่อดึงข้อมูล YouTube ของผู้ใช้ ให้ทำดังนี้

use Google\Client;

$client = new Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfig('client_secret.json');

// Required, to set the scope value, call the addScope function
$client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL);

// Required, call the setRedirectUri function to specify a valid redirect URI for the
// provided client_id
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');

// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType('offline');

// Recommended, call the setState function. Using a state value can increase your assurance that
// an incoming connection is the result of an authentication request.
$client->setState($sample_passthrough_value);

// Optional, if your application knows which user is trying to authenticate, it can use this
// parameter to provide a hint to the Google Authentication Server.
$client->setLoginHint('hint@example.com');

// Optional, call the setPrompt function to set "consent" will prompt the user for consent
$client->setPrompt('consent');

// Optional, call the setIncludeGrantedScopes function with true to enable incremental
// authorization
$client->setIncludeGrantedScopes(true);

Python

ข้อมูลโค้ดต่อไปนี้ใช้โมดูล google-auth-oauthlib.flow เพื่อสร้างคำขอการให้สิทธิ์

โค้ดจะสร้างออบเจ็กต์ Flow ซึ่งระบุแอปพลิเคชันของคุณโดยใช้ข้อมูลจากไฟล์ client_secret.json ที่คุณดาวน์โหลดหลังจากสร้างข้อมูลเข้าสู่ระบบการให้สิทธิ์ ออบเจ็กต์ดังกล่าวจะระบุขอบเขตที่แอปพลิเคชันขอสิทธิ์เข้าถึงและ URL ไปยังปลายทางการตรวจสอบสิทธิ์ของแอปพลิเคชันด้วย ซึ่งจะจัดการการตอบกลับจากเซิร์ฟเวอร์ OAuth 2.0 ของ Google สุดท้าย โค้ดจะตั้งค่าพารามิเตอร์ access_type และ include_granted_scopes (ไม่บังคับ)

ตัวอย่างเช่น หากต้องการขอสิทธิ์เข้าถึงแบบออฟไลน์เพื่อดึงข้อมูล YouTube ของผู้ใช้ ให้ทำดังนี้

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Required, call the from_client_secrets_file method to retrieve the client ID from a
# client_secret.json file. The client ID (from that file) and access scopes are required. (You can
# also use the from_client_config method, which passes the client configuration as it originally
# appeared in a client secrets file but doesn't access the file itself.)
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file('client_secret.json',
    scopes=['https://www.googleapis.com/auth/youtube.force-ssl',
            'https://www.googleapis.com/auth/calendar.readonly'])

# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
flow.redirect_uri = 'https://www.example.com/oauth2callback'

# Generate URL for request to Google's OAuth 2.0 server.
# Use kwargs to set optional request parameters.
authorization_url, state = flow.authorization_url(
    # Recommended, enable offline access so that you can refresh an access token without
    # re-prompting the user for permission. Recommended for web server apps.
    access_type='offline',
    # Optional, enable incremental authorization. Recommended as a best practice.
    include_granted_scopes='true',
    # Optional, if your application knows which user is trying to authenticate, it can use this
    # parameter to provide a hint to the Google Authentication Server.
    login_hint='hint@example.com',
    # Optional, set prompt to 'consent' will prompt the user for consent
    prompt='consent')

Ruby

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

ตัวอย่างเช่น หากต้องการขอสิทธิ์เข้าถึงแบบออฟไลน์เพื่อดึงข้อมูล YouTube ของผู้ใช้ ให้ทำดังนี้

require 'googleauth'
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'

require 'google/apis/youtube_v3'
require 'google/apis/calendar_v3'

# Required, call the from_file method to retrieve the client ID from a
# client_secret.json file.
client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json')

# Required, scope value 
# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
         'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']

# Required, Authorizers require a storage instance to manage long term persistence of
# access and refresh tokens.
token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)

# Required, indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
callback_uri = '/oauth2callback'

# To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
# from the client_secret.json file. To get these credentials for your application, visit
# https://console.cloud.google.com/apis/credentials.
authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope,
                                                token_store, callback_uri)

แอปพลิเคชันใช้ออบเจ็กต์ไคลเอ็นต์เพื่อดำเนินการ OAuth 2.0 เช่น การสร้าง URL คำขอการให้สิทธิ์และการใช้โทเค็นการเข้าถึงกับคำขอ HTTP

Node.js

ข้อมูลโค้ดต่อไปนี้สร้างออบเจ็กต์ google.auth.OAuth2 ซึ่งกําหนดพารามิเตอร์ในคําขอการให้สิทธิ์

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

const {google} = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
 * from the client_secret.json file. To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
const scopes = [
  'https://www.googleapis.com/auth/youtube.force-ssl',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a secure random state value.
const state = crypto.randomBytes(32).toString('hex');

// Store state in the session
req.session.state = state;

// Generate a url that asks permissions for the Drive activity and Google Calendar scope
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as a best practice.
  include_granted_scopes: true,
  // Include the state parameter to reduce the risk of CSRF attacks.
  state: state
});

หมายเหตุสำคัญ - ระบบจะแสดง refresh_token ในการให้สิทธิ์ครั้งแรกเท่านั้น ดูรายละเอียดเพิ่มเติมได้ ที่นี่

HTTP/REST

ปลายทาง 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 จำเป็น

กำหนดว่าปลายทาง OAuth 2.0 ของ Google จะแสดงผลรหัสการให้สิทธิ์หรือไม่

ตั้งค่าพารามิเตอร์เป็น code สําหรับแอปพลิเคชันเว็บเซิร์ฟเวอร์

scope จำเป็น

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

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

YouTube Data API เวอร์ชัน 3 ใช้ขอบเขตต่อไปนี้

กล้องติดปืน
https://www.googleapis.com/auth/youtubeจัดการบัญชี YouTube ของคุณ
https://www.googleapis.com/auth/youtube.channel-memberships.creatorดูรายชื่อสมาชิกปัจจุบันที่ใช้งานอยู่ในช่องของคุณ ระดับปัจจุบันของสมาชิก และวันที่เริ่มเป็นสมาชิก
https://www.googleapis.com/auth/youtube.force-sslดู แก้ไข และลบวิดีโอ YouTube การจัดประเภท ความคิดเห็น และคำบรรยายวิดีโออย่างถาวร
https://www.googleapis.com/auth/youtube.readonlyดูบัญชี YouTube ของคุณ
https://www.googleapis.com/auth/youtube.uploadจัดการวิดีโอ YouTube ของคุณ
https://www.googleapis.com/auth/youtubepartnerดูและจัดการพื้นที่ของคุณและเนื้อหาที่เกี่ยวข้องใน YouTube
https://www.googleapis.com/auth/youtubepartner-channel-auditดูข้อมูลส่วนตัวของช่อง YouTube ของคุณที่เกี่ยวข้องในระหว่างกระบวนการตรวจสอบกับพาร์ทเนอร์ YouTube

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

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

access_type แนะนำ

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

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

state แนะนำ

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

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

include_granted_scopes ไม่บังคับ

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

login_hint ไม่บังคับ

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

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

prompt ไม่บังคับ

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

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

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

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

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

PHP

  1. สร้าง URL เพื่อขอสิทธิ์เข้าถึงจากเซิร์ฟเวอร์ OAuth 2.0 ของ Google โดยทำดังนี้
    $auth_url = $client->createAuthUrl();
  2. เปลี่ยนเส้นทางผู้ใช้ไปยัง $auth_url
    header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));

Python

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

return flask.redirect(authorization_url)

Ruby

  1. สร้าง URL เพื่อขอสิทธิ์เข้าถึงจากเซิร์ฟเวอร์ OAuth 2.0 ของ Google โดยทำดังนี้
    auth_uri = authorizer.get_authorization_url(request: request)
  2. เปลี่ยนเส้นทางผู้ใช้ไปยัง auth_uri

Node.js

  1. ใช้ URL authorizationUrl ที่สร้างขึ้นจากขั้นตอนที่ 1 generateAuthUrl เพื่อขอสิทธิ์เข้าถึงจากเซิร์ฟเวอร์ OAuth 2.0 ของ Google
  2. เปลี่ยนเส้นทางผู้ใช้ไปยัง authorizationUrl
    res.redirect(authorizationUrl);

HTTP/REST

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

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

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 client_id=client_id

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

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

ขั้นตอนที่ 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 จากเว็บไซต์ของคุณ นักพัฒนาแอปควรอนุญาตให้ลิงก์ทั่วไปเปิดในตัวแฮนเดิลลิงก์เริ่มต้นของระบบปฏิบัติการ ซึ่งรวมถึงตัวแฮนเดิล App Link ของ Android หรือแอปเบราว์เซอร์เริ่มต้น นอกจากนี้ ระบบยังรองรับตัวเลือกไลบรารี Android Custom Tabs ด้วย

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

รหัสลับไคลเอ็นต์ OAuth ไม่ถูกต้อง ตรวจสอบการกำหนดค่าไคลเอ็นต์ OAuth รวมถึงรหัสไคลเอ็นต์และรหัสลับที่ใช้สำหรับคำขอนี้

invalid_grant

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

redirect_uri_mismatch

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

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

invalid_request

คำขอที่คุณส่งมามีข้อผิดพลาด ซึ่งอาจเกิดจากสาเหตุหลายประการ ดังนี้

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

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

เซิร์ฟเวอร์ OAuth 2.0 จะตอบกลับคำขอการเข้าถึงของแอปพลิเคชันโดยใช้ URL ที่ระบุในคำขอ

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

การตอบกลับข้อผิดพลาด

https://oauth2.example.com/auth?error=access_denied

การตอบกลับรหัสการให้สิทธิ์

https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7

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

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

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl&
 access_type=offline&
 include_granted_scopes=true&
 response_type=code&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 client_id=client_id

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

ขั้นตอนที่ 5: เปลี่ยนรหัสการให้สิทธิ์เป็นโทเค็นรีเฟรชและโทเค็นการเข้าถึง

หลังจากเว็บเซิร์ฟเวอร์ได้รับรหัสการให้สิทธิ์แล้ว ก็จะแลกเปลี่ยนรหัสการให้สิทธิ์เป็นโทเค็นการเข้าถึงได้

PHP

หากต้องการเปลี่ยนรหัสการให้สิทธิ์เป็นโทเค็นการเข้าถึง ให้ใช้วิธี fetchAccessTokenWithAuthCode ดังนี้

$access_token = $client->fetchAccessTokenWithAuthCode($_GET['code']);

Python

ในหน้าการเรียกกลับ ให้ใช้ไลบรารี google-auth เพื่อยืนยันการตอบกลับของเซิร์ฟเวอร์การให้สิทธิ์ จากนั้นใช้เมธอด flow.fetch_token เพื่อแลกรหัสการให้สิทธิ์ในการตอบกลับนั้นเพื่อรับโทเค็นการเข้าถึง

state = flask.session['state']
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/youtube.force-ssl'],
    state=state)
flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

authorization_response = flask.request.url
flow.fetch_token(authorization_response=authorization_response)

# Store the credentials in the session.
# ACTION ITEM for developers:
#     Store user's access and refresh tokens in your data store if
#     incorporating this code into your real app.
credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'granted_scopes': credentials.granted_scopes}

Ruby

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

  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url

Node.js

หากต้องการเปลี่ยนรหัสการให้สิทธิ์เป็นโทเค็นการเข้าถึง ให้ใช้getTokenวิธีต่อไปนี้

const url = require('url');

// Receive the callback from Google's OAuth 2.0 server.
app.get('/oauth2callback', async (req, res) => {
  let q = url.parse(req.url, true).query;

  if (q.error) { // An error response e.g. error=access_denied
    console.log('Error:' + q.error);
  } else if (q.state !== req.session.state) { //check state value
    console.log('State mismatch. Possible CSRF attack');
    res.end('State mismatch. Possible CSRF attack');
  } else { // Get access and refresh tokens (if access_type is offline)

    let { tokens } = await oauth2Client.getToken(q.code);
    oauth2Client.setCredentials(tokens);
});

HTTP/REST

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

ช่อง
client_id รหัสไคลเอ็นต์ที่ได้รับจาก API Console Credentials page
client_secret รหัสลับไคลเอ็นต์ที่ได้รับจาก API Console Credentials page
code รหัสการให้สิทธิ์ที่แสดงผลจากคำขอเริ่มต้น
grant_type ตามที่กำหนดไว้ในข้อกำหนด OAuth 2.0 ค่าของช่องนี้ต้องตั้งเป็น authorization_code
redirect_uri URI การเปลี่ยนเส้นทางรายการใดรายการหนึ่งสำหรับโปรเจ็กต์ของคุณใน API Console Credentials page สําหรับ client_id

ข้อมูลโค้ดต่อไปนี้แสดงคำขอตัวอย่าง

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code

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

การตอบกลับจะมีฟิลด์ต่อไปนี้

ช่อง
access_token โทเค็นที่แอปพลิเคชันส่งเพื่อให้สิทธิ์คําขอ Google API
expires_in อายุการใช้งานที่เหลือของโทเค็นการเข้าถึงเป็นวินาที
refresh_token โทเค็นที่คุณสามารถใช้รับโทเค็นการเข้าถึงใหม่ โทเค็นรีเฟรชจะใช้ได้จนกว่าผู้ใช้จะเพิกถอนสิทธิ์เข้าถึง โปรดทราบว่าช่องนี้จะปรากฏในการตอบกลับนี้เฉพาะในกรณีที่คุณตั้งค่าพารามิเตอร์ access_type เป็น offline ในคำขอเริ่มต้นไปยังเซิร์ฟเวอร์การให้สิทธิ์ของ Google
scope ขอบเขตการเข้าถึงที่ access_token มอบให้ซึ่งแสดงเป็นรายการสตริงที่เว้นวรรคคั่นและคำนึงถึงตัวพิมพ์เล็กและตัวพิมพ์ใหญ่
token_type ประเภทของโทเค็นที่แสดงผล ขณะนี้ ค่าของช่องนี้จะตั้งไว้เป็น Bearer เสมอ

ข้อมูลโค้ดต่อไปนี้แสดงตัวอย่างคำตอบ

{
  "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
  "expires_in": 3920,
  "token_type": "Bearer",
  "scope": "https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/calendar.readonly",
  "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}

ข้อผิดพลาด

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

invalid_grant

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

ขั้นตอนที่ 6: ตรวจสอบขอบเขตที่ผู้ใช้ให้สิทธิ์

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

PHP

หากต้องการตรวจสอบขอบเขตที่ผู้ใช้ให้สิทธิ์ ให้ใช้เมธอด getGrantedScope() ดังนี้

// Space-separated string of granted scopes if it exists, otherwise null.
$granted_scopes = $client->getOAuth2Service()->getGrantedScope();

// Determine which scopes user granted and build a dictionary
$granted_scopes_dict = [
  'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
  'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
];

Python

ออบเจ็กต์ credentials ที่แสดงผลจะมีพร็อพเพอร์ตี้ granted_scopes ซึ่งเป็นรายการขอบเขตที่ผู้ใช้ให้สิทธิ์แก่แอป

credentials = flow.credentials
flask.session['credentials'] = {
    'token': credentials.token,
    'refresh_token': credentials.refresh_token,
    'token_uri': credentials.token_uri,
    'client_id': credentials.client_id,
    'client_secret': credentials.client_secret,
    'granted_scopes': credentials.granted_scopes}

ฟังก์ชันต่อไปนี้จะตรวจสอบขอบเขตที่ผู้ใช้ให้สิทธิ์แก่แอปของคุณ

def check_granted_scopes(credentials):
  features = {}
  if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['granted_scopes']:
    features['drive'] = True
  else:
    features['drive'] = False

  if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
    features['calendar'] = True
  else:
    features['calendar'] = False

  return features

Ruby

เมื่อขอขอบเขตหลายรายการพร้อมกัน ให้ตรวจสอบขอบเขตที่ได้รับผ่านพร็อพเพอร์ตี้ scope ของออบเจ็กต์ credentials

# User authorized the request. Now, check which scopes were granted.
if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
  # User authorized read-only Drive activity permission.
  # Calling the APIs, etc
else
  # User didn't authorize read-only Drive activity permission.
  # Update UX and application accordingly
end

# Check if user authorized Calendar read permission.
if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
  # User authorized Calendar read permission.
  # Calling the APIs, etc.
else
  # User didn't authorize Calendar read permission.
  # Update UX and application accordingly
end

Node.js

เมื่อขอขอบเขตหลายรายการพร้อมกัน ให้ตรวจสอบขอบเขตที่ได้รับผ่านพร็อพเพอร์ตี้ scope ของออบเจ็กต์ tokens

// User authorized the request. Now, check which scopes were granted.
if (tokens.scope.includes('https://www.googleapis.com/auth/youtube.force-ssl'))
{
  // User authorized read-only Drive activity permission.
  // Calling the APIs, etc.
}
else
{
  // User didn't authorize read-only Drive activity permission.
  // Update UX and application accordingly
}

// Check if user authorized Calendar read permission.
if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
{
  // User authorized Calendar read permission.
  // Calling the APIs, etc.
}
else
{
  // User didn't authorize Calendar read permission.
  // Update UX and application accordingly
}

HTTP/REST

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

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

  {
    "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
    "expires_in": 3920,
    "token_type": "Bearer",
    "scope": "https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/calendar.readonly",
    "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
  }

เรียกใช้ Google API

PHP

ใช้โทเค็นการเข้าถึงเพื่อเรียกใช้ Google API โดยทําตามขั้นตอนต่อไปนี้

  1. หากต้องการใช้โทเค็นการเข้าถึงกับออบเจ็กต์ Google\Client ใหม่ เช่น หากคุณจัดเก็บโทเค็นการเข้าถึงไว้ในเซสชันผู้ใช้ ให้ใช้เมธอด setAccessToken ดังนี้
    $client->setAccessToken($access_token);
  2. สร้างออบเจ็กต์บริการสําหรับ API ที่ต้องการเรียกใช้ คุณสร้างออบเจ็กต์บริการได้โดยระบุออบเจ็กต์ Google\Client ที่มีสิทธิ์ให้กับคอนสตรคเตอร์สําหรับ API ที่ต้องการเรียกใช้ ตัวอย่างเช่น หากต้องการเรียก YouTube Data API ให้ทำดังนี้
    $youtube = new Google_Service_YouTube($client);
  3. ส่งคําขอไปยังบริการ API โดยใช้ อินเทอร์เฟซที่ออบเจ็กต์บริการระบุ ตัวอย่างเช่น หากต้องการใช้ YouTube Data API เพื่อเรียกข้อมูลรายการสตรีมแบบสดของช่องที่ตรวจสอบสิทธิ์แล้วของผู้ใช้ ให้ทำดังนี้
    $broadcasts = $youtube->liveBroadcasts->listLiveBroadcasts('id,snippet', [ 'mine' => true ]);

Python

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

  1. สร้างออบเจ็กต์บริการสําหรับ API ที่ต้องการเรียกใช้ คุณสร้างออบเจ็กต์บริการได้โดยเรียกใช้เมธอด build ของgoogleapiclient.discovery ไลบรารีพร้อมชื่อและเวอร์ชันของ API และข้อมูลเข้าสู่ระบบของผู้ใช้ ดังนี้ ตัวอย่างเช่น หากต้องการเรียกใช้ YouTube Data API เวอร์ชัน 3 ให้ทำดังนี้
    from googleapiclient.discovery import build
    
    youtube = build('youtube', 'v3', credentials=credentials)
  2. ส่งคําขอไปยังบริการ API โดยใช้อินเทอร์เฟซที่ออบเจ็กต์บริการระบุ ตัวอย่างเช่น หากต้องการใช้ YouTube Data API เพื่อเรียกข้อมูลรายการสตรีมแบบสดของช่องที่ตรวจสอบสิทธิ์แล้วของผู้ใช้ ให้ทำดังนี้
    broadcasts = youtube.liveBroadcasts().list(part='id,snippet', mine=True).execute()

Ruby

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

  1. สร้างออบเจ็กต์บริการสําหรับ API ที่ต้องการเรียกใช้ เช่น หากต้องการเรียกใช้ YouTube Data API เวอร์ชัน 3 ให้ทำดังนี้
    youtube = Google::Apis::YoutubeV3::YouTubeService.new
  2. ตั้งค่าข้อมูลเข้าสู่ระบบในบริการ
    youtube.authorization = credentials
  3. ส่งคําขอไปยังบริการ API โดยใช้อินเทอร์เฟซที่ออบเจ็กต์บริการระบุ ตัวอย่างเช่น หากต้องการใช้ YouTube Data API เพื่อเรียกข้อมูลรายการสตรีมแบบสดของช่องที่ตรวจสอบสิทธิ์แล้วของผู้ใช้ ให้ทำดังนี้
    broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true)

หรือจะให้สิทธิ์ตามวิธีการแต่ละวิธีก็ได้โดยระบุพารามิเตอร์ options ให้กับวิธีการ

broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true)

Node.js

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

const { google } = require('googleapis');

// 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) => {
  if (err1) return console.log('The API returned an error: ' + err1);
  const files = res1.data.files;
  if (files.length) {
    console.log('Files:');
    files.map((file) => {
      console.log(`${file.name} (${file.id})`);
    });
  } else {
    console.log('No files found.');
  }
});

HTTP/REST

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

โปรดทราบว่า YouTube Live Streaming API ไม่รองรับขั้นตอนสำหรับบัญชีบริการ เนื่องจากไม่สามารถลิงก์บัญชีบริการกับบัญชี YouTube ได้ การพยายามให้สิทธิ์คำขอด้วยขั้นตอนนี้จะทำให้เกิดข้อผิดพลาด NoLinkedYouTubeAccount

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

ตัวอย่าง HTTP GET

การเรียกใช้ปลายทาง (YouTube Live Streaming API) liveBroadcasts.list โดยใช้ส่วนหัว HTTP ของ Authorization: Bearer อาจมีลักษณะดังนี้ โปรดทราบว่าคุณต้องระบุโทเค็นการเข้าถึงของคุณเอง โดยทำดังนี้

GET /youtube/v3/liveBroadcasts?part=id%2Csnippet&mine=true HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

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

GET https://www.googleapis.com/youtube/v3/liveBroadcasts?access_token=access_token&part=id%2Csnippet&mine=true

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

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

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/liveBroadcasts?part=id%2Csnippet&mine=true

หรือจะใช้ตัวเลือกพารามิเตอร์สตริงการค้นหาก็ได้

curl https://www.googleapis.com/youtube/v3/liveBroadcasts?access_token=access_token&part=id%2Csnippet&mine=true

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

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

PHP

วิธีเรียกใช้ตัวอย่างนี้

  1. ใน API Consoleให้เพิ่ม URL ของเครื่องในเครื่องลงในรายการ URL การเปลี่ยนเส้นทาง เช่น เพิ่ม http://localhost:8080
  2. สร้างไดเรกทอรีใหม่และเปลี่ยนไปใช้ไดเรกทอรีนั้น เช่น
    mkdir ~/php-oauth2-example
    cd ~/php-oauth2-example
  3. ติดตั้งไลบรารีของไคลเอ็นต์ Google API สำหรับ PHP โดยใช้ Composer
    composer require google/apiclient:^2.15.0
  4. สร้างไฟล์ index.php และ oauth2callback.php ที่มีเนื้อหาต่อไปนี้
  5. เรียกใช้ตัวอย่างด้วยเว็บเซิร์ฟเวอร์ทดสอบในตัวของ PHP ดังนี้
    php -S localhost:8080 ~/php-oauth2-example

index.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();
$client->setAuthConfig('client_secret.json');

// User granted permission as an access token is in the session.
if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
{
  $client->setAccessToken($_SESSION['access_token']);
  
  // Check if user granted Drive permission
  if ($_SESSION['granted_scopes_dict']['Drive']) {
    echo "Drive feature is enabled.";
    echo "</br>";
    $drive = new Drive($client);
    $files = array();
    $response = $drive->files->listFiles(array());
    foreach ($response->files as $file) {
        echo "File: " . $file->name . " (" . $file->id . ")";
        echo "</br>";
    }
  } else {
    echo "Drive feature is NOT enabled.";
    echo "</br>";
  }

   // Check if user granted Calendar permission
  if ($_SESSION['granted_scopes_dict']['Calendar']) {
    echo "Calendar feature is enabled.";
    echo "</br>";
  } else {
    echo "Calendar feature is NOT enabled.";
    echo "</br>";
  }
}
else
{
  // Redirect users to outh2call.php which redirects users to Google OAuth 2.0
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>

oauth2callback.php

<?php
require_once __DIR__.'/vendor/autoload.php';

session_start();

$client = new Google\Client();

// Required, call the setAuthConfig function to load authorization credentials from
// client_secret.json file.
$client->setAuthConfigFile('client_secret.json');
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST']. $_SERVER['PHP_SELF']);

// Required, to set the scope value, call the addScope function.
$client->addScope(Google_Service_YouTube::YOUTUBE_FORCE_SSL);

// Enable incremental authorization. Recommended as a best practice.
$client->setIncludeGrantedScopes(true);

// Recommended, offline access will give you both an access and refresh token so that
// your app can refresh the access token without user interaction.
$client->setAccessType("offline");

// Generate a URL for authorization as it doesn't contain code and error
if (!isset($_GET['code']) && !isset($_GET['error']))
{
  // Generate and set state value
  $state = bin2hex(random_bytes(16));
  $client->setState($state);
  $_SESSION['state'] = $state;

  // Generate a url that asks permissions.
  $auth_url = $client->createAuthUrl();
  header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
}

// User authorized the request and authorization code is returned to exchange access and
// refresh tokens.
if (isset($_GET['code']))
{
  // Check the state value
  if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) {
    die('State mismatch. Possible CSRF attack.');
  }

  // Get access and refresh tokens (if access_type is offline)
  $token = $client->fetchAccessTokenWithAuthCode($_GET['code']);

  /** Save access and refresh token to the session variables.
    * ACTION ITEM: In a production app, you likely want to save the
    *              refresh token in a secure persistent storage instead. */
  $_SESSION['access_token'] = $token;
  $_SESSION['refresh_token'] = $client->getRefreshToken();
  
  // Space-separated string of granted scopes if it exists, otherwise null.
  $granted_scopes = $client->getOAuth2Service()->getGrantedScope();

  // Determine which scopes user granted and build a dictionary
  $granted_scopes_dict = [
    'Drive' => str_contains($granted_scopes, Google\Service\Drive::DRIVE_METADATA_READONLY),
    'Calendar' => str_contains($granted_scopes, Google\Service\Calendar::CALENDAR_READONLY)
  ];
  $_SESSION['granted_scopes_dict'] = $granted_scopes_dict;
  
  $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/';
  header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}

// An error response e.g. error=access_denied
if (isset($_GET['error']))
{
  echo "Error: ". $_GET['error'];
}
?>

Python

ตัวอย่างนี้ใช้เฟรมเวิร์ก Flask ซึ่งจะเรียกใช้เว็บแอปพลิเคชันที่ http://localhost:8080 ให้คุณทดสอบขั้นตอน OAuth 2.0 เมื่อไปที่ URL ดังกล่าว คุณควรเห็นลิงก์ 5 รายการดังนี้

  • เรียกใช้ Drive API: ลิงก์นี้จะไปยังหน้าที่พยายามเรียกใช้คําขอ API ตัวอย่างหากผู้ใช้ให้สิทธิ์ และเริ่มขั้นตอนการให้สิทธิ์หากจําเป็น หากสําเร็จ หน้าเว็บจะแสดงการตอบกลับของ API
  • หน้าจำลองเพื่อเรียกใช้ปฏิทิน API: ลิงก์นี้จะไปยังหน้าจำลองที่พยายามเรียกใช้คำขอตัวอย่างปฏิทิน API หากผู้ใช้ให้สิทธิ์ และเริ่มขั้นตอนการให้สิทธิ์หากจําเป็น หากสําเร็จ หน้าเว็บจะแสดงการตอบกลับของ API
  • ทดสอบขั้นตอนการให้สิทธิ์โดยตรง: ลิงก์นี้จะไปยังหน้าที่พยายามส่งผู้ใช้ผ่านขั้นตอนการให้สิทธิ์ แอปขอสิทธิ์ในการส่งคําขอ API ที่ได้รับอนุญาตในนามของผู้ใช้
  • เพิกถอนข้อมูลเข้าสู่ระบบปัจจุบัน: ลิงก์นี้จะไปยังหน้าที่ เพิกถอนสิทธิ์ที่ผู้ใช้ให้ไว้กับแอปพลิเคชันแล้ว
  • ล้างข้อมูลเข้าสู่ระบบเซสชัน Flask: ลิงก์นี้จะล้างข้อมูลเข้าสู่ระบบการให้สิทธิ์ที่จัดเก็บไว้ในเซสชัน Flask ซึ่งจะช่วยให้คุณเห็นว่าจะเกิดอะไรขึ้นหากผู้ใช้ที่เคยให้สิทธิ์แก่แอปของคุณพยายามเรียกใช้คําขอ API ในเซสชันใหม่ นอกจากนี้ คุณยังดูการตอบกลับของ API ที่แอปจะได้รับได้หากผู้ใช้เพิกถอนสิทธิ์ที่มอบให้แอป และแอปยังคงพยายามให้สิทธิ์คําขอด้วยโทเค็นการเข้าถึงที่ถูกเพิกถอน
# -*- coding: utf-8 -*-

import os
import flask
import requests

import google.oauth2.credentials
import google_auth_oauthlib.flow
import googleapiclient.discovery

# This variable specifies the name of a file that contains the OAuth 2.0
# information for this application, including its client_id and client_secret.
CLIENT_SECRETS_FILE = "client_secret.json"

# The OAuth 2.0 access scope allows for access to the
# authenticated user's account and requires requests to use an SSL connection.
SCOPES = ['https://www.googleapis.com/auth/youtube.force-ssl',
          'https://www.googleapis.com/auth/calendar.readonly']
API_SERVICE_NAME = 'youtube'
API_VERSION = 'v3'

app = flask.Flask(__name__)
# Note: A secret key is included in the sample so that it works.
# If you use this code in your application, replace this with a truly secret
# key. See https://flask.palletsprojects.com/quickstart/#sessions.
app.secret_key = 'REPLACE ME - this value is here as a placeholder.'

@app.route('/')
def index():
  return print_index_table()

@app.route('/drive')
def drive_api_request():
  if 'credentials' not in flask.session:
    return flask.redirect('authorize')

  features = flask.session['features']

  if features['drive']:
    # Load credentials from the session.
    credentials = google.oauth2.credentials.Credentials(
        **flask.session['credentials'])

    youtube = googleapiclient.discovery.build(
        API_SERVICE_NAME, API_VERSION, credentials=credentials)

    broadcasts = youtube.liveBroadcasts().list(part='id,snippet', mine=True).execute()

    # Save credentials back to session in case access token was refreshed.
    # ACTION ITEM: In a production app, you likely want to save these
    #              credentials in a persistent database instead.
    flask.session['credentials'] = credentials_to_dict(credentials)

    return flask.jsonify(**broadcasts)
  else:
    # User didn't authorize read-only Drive activity permission.
    # Update UX and application accordingly
    return '<p>Drive feature is not enabled.</p>'

@app.route('/calendar')
    def calendar_api_request():
      if 'credentials' not in flask.session:
        return flask.redirect('authorize')

      features = flask.session['features']

      if features['calendar']:
        # User authorized Calendar read permission.
        # Calling the APIs, etc.
        return ('<p>User granted the Google Calendar read permission. '+
                'This sample code does not include code to call Calendar</p>')
      else:
        # User didn't authorize Calendar read permission.
        # Update UX and application accordingly
        return '<p>Calendar feature is not enabled.</p>'

@app.route('/authorize')
def authorize():
  # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps.
  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES)

  # The URI created here must exactly match one of the authorized redirect URIs
  # for the OAuth 2.0 client, which you configured in the API Console. If this
  # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch'
  # error.
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  authorization_url, state = flow.authorization_url(
      # Enable offline access so that you can refresh an access token without
      # re-prompting the user for permission. Recommended for web server apps.
      access_type='offline',
      # Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes='true')

  # Store the state so the callback can verify the auth server response.
  flask.session['state'] = state

  return flask.redirect(authorization_url)

@app.route('/oauth2callback')
def oauth2callback():
  # Specify the state when creating the flow in the callback so that it can
  # verified in the authorization server response.
  state = flask.session['state']

  flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
      CLIENT_SECRETS_FILE, scopes=SCOPES, state=state)
  flow.redirect_uri = flask.url_for('oauth2callback', _external=True)

  # Use the authorization server's response to fetch the OAuth 2.0 tokens.
  authorization_response = flask.request.url
  flow.fetch_token(authorization_response=authorization_response)

  # Store credentials in the session.
  # ACTION ITEM: In a production app, you likely want to save these
  #              credentials in a persistent database instead.
  credentials = flow.credentials
  
  credentials = credentials_to_dict(credentials)
  flask.session['credentials'] = credentials

  # Check which scopes user granted
  features = check_granted_scopes(credentials)
  flask.session['features'] = features
  return flask.redirect('/')
  

@app.route('/revoke')
def revoke():
  if 'credentials' not in flask.session:
    return ('You need to <a href="/authorize">authorize</a> before ' +
            'testing the code to revoke credentials.')

  credentials = google.oauth2.credentials.Credentials(
    **flask.session['credentials'])

  revoke = requests.post('https://oauth2.googleapis.com/revoke',
      params={'token': credentials.token},
      headers = {'content-type': 'application/x-www-form-urlencoded'})

  status_code = getattr(revoke, 'status_code')
  if status_code == 200:
    return('Credentials successfully revoked.' + print_index_table())
  else:
    return('An error occurred.' + print_index_table())

@app.route('/clear')
def clear_credentials():
  if 'credentials' in flask.session:
    del flask.session['credentials']
  return ('Credentials have been cleared.<br><br>' +
          print_index_table())

def credentials_to_dict(credentials):
  return {'token': credentials.token,
          'refresh_token': credentials.refresh_token,
          'token_uri': credentials.token_uri,
          'client_id': credentials.client_id,
          'client_secret': credentials.client_secret,
          'granted_scopes': credentials.granted_scopes}

def check_granted_scopes(credentials):
  features = {}
  if 'https://www.googleapis.com/auth/youtube.force-ssl' in credentials['granted_scopes']:
    features['drive'] = True
  else:
    features['drive'] = False

  if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['granted_scopes']:
    features['calendar'] = True
  else:
    features['calendar'] = False

  return features

def print_index_table():
  return ('<table>' +
          '<tr><td><a href="/test">Test an API request</a></td>' +
          '<td>Submit an API request and see a formatted JSON response. ' +
          '    Go through the authorization flow if there are no stored ' +
          '    credentials for the user.</td></tr>' +
          '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' +
          '<td>Go directly to the authorization flow. If there are stored ' +
          '    credentials, you still might not be prompted to reauthorize ' +
          '    the application.</td></tr>' +
          '<tr><td><a href="/revoke">Revoke current credentials</a></td>' +
          '<td>Revoke the access token associated with the current user ' +
          '    session. After revoking credentials, if you go to the test ' +
          '    page, you should see an <code>invalid_grant</code> error.' +
          '</td></tr>' +
          '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' +
          '<td>Clear the access token currently stored in the user session. ' +
          '    After clearing the token, if you <a href="/test">test the ' +
          '    API request</a> again, you should go back to the auth flow.' +
          '</td></tr></table>')

if __name__ == '__main__':
  # When running locally, disable OAuthlib's HTTPs verification.
  # ACTION ITEM for developers:
  #     When running in production *do not* leave this option enabled.
  os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1'

  # This disables the requested scopes and granted scopes check.
  # If users only grant partial request, the warning would not be thrown.
  os.environ['OAUTHLIB_RELAX_TOKEN_SCOPE'] = '1'

  # Specify a hostname and port that are set as a valid redirect URI
  # for your API project in the Google API Console.
  app.run('localhost', 8080, debug=True)

Ruby

ตัวอย่างนี้ใช้เฟรมเวิร์ก Sinatra

require 'googleauth'
require 'googleauth/web_user_authorizer'
require 'googleauth/stores/redis_token_store'

require 'google/apis/youtube_v3'
require 'google/apis/calendar_v3'

require 'sinatra'

configure do
  enable :sessions

  # Required, call the from_file method to retrieve the client ID from a
  # client_secret.json file.
  set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json')

  # Required, scope value
  # Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
  scope = ['Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY',
           'Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY']

  # Required, Authorizers require a storage instance to manage long term persistence of
  # access and refresh tokens.
  set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new)

  # Required, indicate where the API server will redirect the user after the user completes
  # the authorization flow. The redirect URI is required. The value must exactly
  # match one of the authorized redirect URIs for the OAuth 2.0 client, which you
  # configured in the API Console. If this value doesn't match an authorized URI,
  # you will get a 'redirect_uri_mismatch' error.
  set :callback_uri, '/oauth2callback'

  # To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
  # from the client_secret.json file. To get these credentials for your application, visit
  # https://console.cloud.google.com/apis/credentials.
  set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope,
                          settings.token_store, callback_uri: settings.callback_uri)
end

get '/' do
  # NOTE: Assumes the user is already authenticated to the app
  user_id = request.session['user_id']

  # Fetch stored credentials for the user from the given request session.
  # nil if none present
  credentials = settings.authorizer.get_credentials(user_id, request)

  if credentials.nil?
    # Generate a url that asks the user to authorize requested scope(s).
    # Then, redirect user to the url.
    redirect settings.authorizer.get_authorization_url(request: request)
  end
  
  # User authorized the request. Now, check which scopes were granted.
  if credentials.scope.include?(Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY)
    # User authorized read-only Drive activity permission.
    # Example of using Google Drive API to list filenames in user's Drive.
    youtube = Google::Apis::YoutubeV3::YouTubeService.new
    broadcasts = youtube.list_liveBroadcasts('id,snippet', mine: true)
    
    "<pre>#{JSON.pretty_generate(broadcasts.to_h)}</pre>"
  else
    # User didn't authorize read-only Drive activity permission.
    # Update UX and application accordingly
  end

  # Check if user authorized Calendar read permission.
  if credentials.scope.include?(Google::Apis::CalendarV3::AUTH_CALENDAR_READONLY)
    # User authorized Calendar read permission.
    # Calling the APIs, etc.
  else
    # User didn't authorize Calendar read permission.
    # Update UX and application accordingly
  end
end

# Receive the callback from Google's OAuth 2.0 server.
get '/oauth2callback' do
  # Handle the result of the oauth callback. Defers the exchange of the code by
  # temporarily stashing the results in the user's session.
  target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request)
  redirect target_url
end

Node.js

วิธีเรียกใช้ตัวอย่างนี้

  1. ใน API Consoleให้เพิ่ม URL ของเครื่องที่ใช้งานอยู่ลงในรายการ URL การเปลี่ยนเส้นทาง เช่น เพิ่ม http://localhost
  2. ตรวจสอบว่าคุณได้ติดตั้ง LTS เวอร์ชันปัจจุบัน, LTS ที่ใช้งานอยู่ หรือ LTS เวอร์ชันการบำรุงรักษาของ Node.js แล้ว
  3. สร้างไดเรกทอรีใหม่และเปลี่ยนไปใช้ไดเรกทอรีนั้น เช่น
    mkdir ~/nodejs-oauth2-example
    cd ~/nodejs-oauth2-example
  4. ติดตั้งไลบรารีของไคลเอ็นต์ Google API สำหรับ Node.js โดยใช้ npm
    npm install googleapis
  5. สร้างไฟล์ main.js ที่มีเนื้อหาต่อไปนี้
  6. เรียกใช้ตัวอย่าง
    node .\main.js

main.js

const http = require('http');
const https = require('https');
const url = require('url');
const { google } = require('googleapis');
const crypto = require('crypto');
const express = require('express');
const session = require('express-session');

/**
 * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI.
 * To get these credentials for your application, visit
 * https://console.cloud.google.com/apis/credentials.
 */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
const scopes = [
  'https://www.googleapis.com/auth/youtube.force-ssl',
  'https://www.googleapis.com/auth/calendar.readonly'
];

/* Global variable that stores user credential in this code example.
 * ACTION ITEM for developers:
 *   Store user's refresh token in your data store if
 *   incorporating this code into your real app.
 *   For more information on handling refresh tokens,
 *   see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens
 */
let userCredential = null;

async function main() {
  const app = express();

  app.use(session({
    secret: 'your_secure_secret_key', // Replace with a strong secret
    resave: false,
    saveUninitialized: false,
  }));

  // Example on redirecting user to Google's OAuth 2.0 server.
  app.get('/', async (req, res) => {
    // Generate a secure random state value.
    const state = crypto.randomBytes(32).toString('hex');
    // Store state in the session
    req.session.state = state;

    // Generate a url that asks permissions for the Drive activity and Google Calendar scope
    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true,
      // Include the state parameter to reduce the risk of CSRF attacks.
      state: state
    });

    res.redirect(authorizationUrl);
  });

  // Receive the callback from Google's OAuth 2.0 server.
  app.get('/oauth2callback', async (req, res) => {
    // Handle the OAuth 2.0 server response
    let q = url.parse(req.url, true).query;

    if (q.error) { // An error response e.g. error=access_denied
      console.log('Error:' + q.error);
    } else if (q.state !== req.session.state) { //check state value
      console.log('State mismatch. Possible CSRF attack');
      res.end('State mismatch. Possible CSRF attack');
    } else { // Get access and refresh tokens (if access_type is offline)
      let { tokens } = await oauth2Client.getToken(q.code);
      oauth2Client.setCredentials(tokens);

      /** Save credential to the global variable in case access token was refreshed.
        * ACTION ITEM: In a production app, you likely want to save the refresh token
        *              in a secure persistent database instead. */
      userCredential = tokens;
      
      // User authorized the request. Now, check which scopes were granted.
      if (tokens.scope.includes('https://www.googleapis.com/auth/youtube.force-ssl'))
      {
        // User authorized read-only Drive activity permission.
        // 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) => {
          if (err1) return console.log('The API returned an error: ' + err1);
          const files = res1.data.files;
          if (files.length) {
            console.log('Files:');
            files.map((file) => {
              console.log(`${file.name} (${file.id})`);
            });
          } else {
            console.log('No files found.');
          }
        });
      }
      else
      {
        // User didn't authorize read-only Drive activity permission.
        // Update UX and application accordingly
      }

      // Check if user authorized Calendar read permission.
      if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
      {
        // User authorized Calendar read permission.
        // Calling the APIs, etc.
      }
      else
      {
        // User didn't authorize Calendar read permission.
        // Update UX and application accordingly
      }
    }
  });

  // Example on revoking a token
  app.get('/revoke', async (req, res) => {
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;

    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };

    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });

    postReq.on('error', error => {
      console.log(error)
    });

    // Post the request with data
    postReq.write(postData);
    postReq.end();
  });


  const server = http.createServer(app);
  server.listen(8080);
}
main().catch(console.error);

HTTP/REST

ตัวอย่าง Python นี้ใช้เฟรมเวิร์ก Flask และไลบรารี Requests เพื่อสาธิตเวฟเฟอร์ OAuth 2.0 เราขอแนะนําให้ใช้ไลบรารีของไคลเอ็นต์ Google API สําหรับ Python ในขั้นตอนนี้ (ตัวอย่างในแท็บ Python ใช้ไลบรารีของไคลเอ็นต์)

import json
import flask
import requests

app = flask.Flask(__name__)

# To get these credentials (CLIENT_ID CLIENT_SECRET) and for your application, visit
# https://console.cloud.google.com/apis/credentials.
CLIENT_ID = '123456789.apps.googleusercontent.com'
CLIENT_SECRET = 'abc123'  # Read from a file or environmental variable in a real app

# Access scopes for two non-Sign-In scopes: Read-only Drive activity and Google Calendar.
SCOPE = 'https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/calendar.readonly'

# Indicate where the API server will redirect the user after the user completes
# the authorization flow. The redirect URI is required. The value must exactly
# match one of the authorized redirect URIs for the OAuth 2.0 client, which you
# configured in the API Console. If this value doesn't match an authorized URI,
# you will get a 'redirect_uri_mismatch' error.
REDIRECT_URI = 'http://example.com/oauth2callback'

@app.route('/')
def index():
  if 'credentials' not in flask.session:
    return flask.redirect(flask.url_for('oauth2callback'))

  credentials = json.loads(flask.session['credentials'])

  if credentials['expires_in'] <= 0:
    return flask.redirect(flask.url_for('oauth2callback'))
  else: 
    # User authorized the request. Now, check which scopes were granted.
    if 'https://www.googleapis.com/auth/drive.metadata.readonly' in credentials['scope']:
      # User authorized read-only Drive activity permission.
      # Example of using Google Drive API to list filenames in user's Drive.
      headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])}
      req_uri = 'https://youtube.googleapis.com/youtube/v3/liveBroadcasts'
      r = requests.get(req_uri, headers=headers).text
    else:
      # User didn't authorize read-only Drive activity permission.
      # Update UX and application accordingly
      r = 'User did not authorize Drive permission.'

    # Check if user authorized Calendar read permission.
    if 'https://www.googleapis.com/auth/calendar.readonly' in credentials['scope']:
      # User authorized Calendar read permission.
      # Calling the APIs, etc.
      r += 'User authorized Calendar permission.'
    else:
      # User didn't authorize Calendar read permission.
      # Update UX and application accordingly
      r += 'User did not authorize Calendar permission.'

  return r

@app.route('/oauth2callback')
def oauth2callback():
  if 'code' not in flask.request.args:
    state = str(uuid.uuid4())
    flask.session['state'] = state
    # Generate a url that asks permissions for the Drive activity
    # and Google Calendar scope. Then, redirect user to the url.
    auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code'
                '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI,
                                                                          SCOPE, state)
    return flask.redirect(auth_uri)
  else:
    if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']:
      return 'State mismatch. Possible CSRF attack.', 400

    auth_code = flask.request.args.get('code')
    data = {'code': auth_code,
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'redirect_uri': REDIRECT_URI,
            'grant_type': 'authorization_code'}

    # Exchange authorization code for access and refresh tokens (if access_type is offline)
    r = requests.post('https://oauth2.googleapis.com/token', data=data)
    flask.session['credentials'] = r.text
    return flask.redirect(flask.url_for('index'))

if __name__ == '__main__':
  import uuid
  app.secret_key = str(uuid.uuid4())
  app.debug = False
  app.run()

กฎการตรวจสอบ URI การเปลี่ยนเส้นทาง

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

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

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

โฮสต์

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

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

    URI การเปลี่ยนเส้นทางต้องไม่มีคอมโพเนนต์ย่อย userinfo

    เส้นทาง

    URI การเปลี่ยนเส้นทางต้องไม่มี Path Traversal (หรือที่เรียกว่าการย้อนกลับไดเรกทอรี) ซึ่งแสดงด้วย “/..” หรือ “\..” หรือการแปลง URL

    การค้นหา

    URI การเปลี่ยนเส้นทางต้องไม่มีการเปลี่ยนเส้นทางแบบเปิด

    เศษข้อความ

    URI การเปลี่ยนเส้นทางต้องไม่มีคอมโพเนนต์ของ URL ย่อย

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

    การให้สิทธิ์เพิ่มเติม

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

    ตัวอย่างเช่น สมมติว่าแอปดึงข้อมูลสําหรับช่อง YouTube ของผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์ และช่วยให้ผู้ใช้ดึงข้อมูล YouTube Analytics ผ่านขั้นตอนพิเศษได้ ในกรณีนี้ เมื่อลงชื่อเข้าใช้ แอปอาจขอสิทธิ์เข้าถึงเฉพาะขอบเขต https://www.googleapis.com/auth/youtube.force-ssl เท่านั้น อย่างไรก็ตาม หากผู้ใช้พยายามเข้าถึงข้อมูล Analytics สําหรับช่อง แอปอาจขอสิทธิ์เข้าถึงขอบเขต https://www.googleapis.com/auth/yt-analytics.readonly ด้วย

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

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

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

    ตัวอย่างโค้ดเฉพาะภาษาในขั้นตอนที่ 1: ตั้งค่าพารามิเตอร์การให้สิทธิ์และตัวอย่าง URL การเปลี่ยนเส้นทาง HTTP/REST ในขั้นตอนที่ 2: เปลี่ยนเส้นทางไปยังเซิร์ฟเวอร์ OAuth 2.0 ของ Google ทั้งหมดใช้การให้สิทธิ์แบบเพิ่ม ตัวอย่างโค้ดด้านล่างยังแสดงโค้ดที่คุณต้องเพิ่มเพื่อใช้การให้สิทธิ์แบบเพิ่ม

    PHP

    $client->setIncludeGrantedScopes(true);

    Python

    ใน Python ให้ตั้งค่าอาร์กิวเมนต์คีย์เวิร์ด include_granted_scopes เป็น true เพื่อให้คำขอการให้สิทธิ์มีขอบเขตที่ได้รับอนุญาตก่อนหน้านี้ เป็นไปได้มากว่า include_granted_scopes จะไม่ได้เป็นอาร์กิวเมนต์คีย์เวิร์ดเพียงรายการเดียวที่คุณตั้งค่าไว้ ดังที่แสดงในตัวอย่างด้านล่าง

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

    Ruby

    auth_client.update!(
      :additional_parameters => {"include_granted_scopes" => "true"}
    )

    Node.js

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });

    HTTP/REST

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

    GET https://accounts.google.com/o/oauth2/v2/auth?
      scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.force-ssl&
      access_type=offline&
      state=security_token%3D138rk%3Btarget_url%3Dhttp...index&
      redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
      response_type=code&
      client_id=client_id&
      include_granted_scopes=true
    
          

    Refreshing an access token (offline access)

    Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.

    • If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
    • If you are not using a client library, you need to set the access_type HTTP query parameter to offline when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.

    Requesting offline access is a requirement for any application that needs to access a Google API when the user is not present. For example, an app that performs backup services or executes actions at predetermined times needs to be able to refresh its access token when the user is not present. The default style of access is called online.

    Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.

    PHP

    If your application needs offline access to a Google API, set the API client's access type to offline:

    $client->setAccessType("offline");

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

    Python

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

    authorization_url, state = flow.authorization_url(
        # Enable offline access so that you can refresh an access token without
        # re-prompting the user for permission. Recommended for web server apps.
        access_type='offline',
        # Enable incremental authorization. Recommended as a best practice.
        include_granted_scopes='true')

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

    Ruby

    หากแอปพลิเคชันของคุณต้องใช้สิทธิ์เข้าถึงแบบออฟไลน์ใน Google API ให้ตั้งค่าประเภทการเข้าถึงของไคลเอ็นต์ API เป็น offline ดังนี้

    auth_client.update!(
      :additional_parameters => {"access_type" => "offline"}
    )

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

    Node.js

    หากแอปพลิเคชันของคุณต้องใช้สิทธิ์เข้าถึงแบบออฟไลน์ใน Google API ให้ตั้งค่าประเภทการเข้าถึงของไคลเอ็นต์ API เป็น offline ดังนี้

    const authorizationUrl = oauth2Client.generateAuthUrl({
      // 'online' (default) or 'offline' (gets refresh_token)
      access_type: 'offline',
      /** Pass in the scopes array defined above.
        * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
      scope: scopes,
      // Enable incremental authorization. Recommended as a best practice.
      include_granted_scopes: true
    });

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

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

    oauth2Client.on('tokens', (tokens) => {
      if (tokens.refresh_token) {
        // store the refresh_token in your secure persistent database
        console.log(tokens.refresh_token);
      }
      console.log(tokens.access_token);
    });

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

    หากต้องการตั้งค่า refresh_token ในภายหลัง คุณสามารถใช้วิธีการ setCredentials ดังนี้

    oauth2Client.setCredentials({
      refresh_token: `STORED_REFRESH_TOKEN`
    });

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

    HTTP/REST

    หากต้องการรีเฟรชโทเค็นการเข้าถึง แอปพลิเคชันจะส่งคําขอ HTTPS POST ไปยังเซิร์ฟเวอร์การให้สิทธิ์ของ Google (https://oauth2.googleapis.com/token) ซึ่งมีพารามิเตอร์ต่อไปนี้

    ช่อง
    client_id รหัสไคลเอ็นต์ที่ได้รับจาก API Console
    client_secret รหัสลับไคลเอ็นต์ที่ได้รับจาก API Console
    grant_type คุณต้องตั้งค่าช่องนี้เป็น refresh_token ตามที่ระบุไว้ในข้อกำหนดเฉพาะของ OAuth 2.0
    refresh_token โทเค็นการรีเฟรชที่แสดงผลจากการแลกเปลี่ยนรหัสการให้สิทธิ์

    ข้อมูลโค้ดต่อไปนี้แสดงคำขอตัวอย่าง

    POST /token HTTP/1.1
    Host: oauth2.googleapis.com
    Content-Type: application/x-www-form-urlencoded
    
    client_id=your_client_id&
    client_secret=your_client_secret&
    refresh_token=refresh_token&
    grant_type=refresh_token

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

    {
      "access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
      "expires_in": 3920,
      "scope": "https://www.googleapis.com/auth/drive.metadata.readonly https://www.googleapis.com/auth/calendar.readonly",
      "token_type": "Bearer"
    }

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

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

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

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

    PHP

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

    $client->revokeToken();

    Python

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

    requests.post('https://oauth2.googleapis.com/revoke',
        params={'token': credentials.token},
        headers = {'content-type': 'application/x-www-form-urlencoded'})

    Ruby

    หากต้องการเพิกถอนโทเค็นแบบเป็นโปรแกรม ให้ส่งคําขอ HTTP ไปยังปลายทาง oauth2.revoke ดังนี้

    uri = URI('https://oauth2.googleapis.com/revoke')
    response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)

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

    หากการเพิกถอนดำเนินการเสร็จสมบูรณ์ รหัสสถานะของการตอบกลับจะเป็น 200 สำหรับเงื่อนไขข้อผิดพลาด ระบบจะแสดงรหัสสถานะ 400 พร้อมกับรหัสข้อผิดพลาด

    Node.js

    หากต้องการเพิกถอนโทเค็นแบบเป็นโปรแกรม ให้ส่งคําขอ HTTPS POST ไปยังปลายทาง /revoke ต่อไปนี้

    const https = require('https');
    
    // Build the string for the POST request
    let postData = "token=" + userCredential.access_token;
    
    // Options for POST request to Google's OAuth 2.0 server to revoke a token
    let postOptions = {
      host: 'oauth2.googleapis.com',
      port: '443',
      path: '/revoke',
      method: 'POST',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded',
        'Content-Length': Buffer.byteLength(postData)
      }
    };
    
    // Set up the request
    const postReq = https.request(postOptions, function (res) {
      res.setEncoding('utf8');
      res.on('data', d => {
        console.log('Response: ' + d);
      });
    });
    
    postReq.on('error', error => {
      console.log(error)
    });
    
    // Post the request with data
    postReq.write(postData);
    postReq.end();

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

    หากการเพิกถอนดำเนินการเสร็จสมบูรณ์ รหัสสถานะของการตอบกลับจะเป็น 200 สำหรับเงื่อนไขข้อผิดพลาด ระบบจะแสดงรหัสสถานะ 400 พร้อมกับรหัสข้อผิดพลาด

    HTTP/REST

    หากต้องการเพิกถอนโทเค็นแบบเป็นโปรแกรม แอปพลิเคชันของคุณจะต้องส่งคำขอไปที่ 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 พร้อมกับรหัสข้อผิดพลาด

    การใช้การป้องกันแบบครอบคลุมหลายบริการ

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

    ตัวอย่างประเภทเหตุการณ์ที่บริการการปกป้องบัญชีข้ามของ Google ส่งไปยังแอปของคุณมีดังนี้

    • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
    • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
    • https://schemas.openid.net/secevent/risc/event-type/account-disabled

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