OpenID Connect

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

การตั้งค่า OAuth 2.0

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

รับข้อมูลเข้าสู่ระบบ OAuth 2.0

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

ในการดูรหัสลูกค้าและข้อมูลลับของลูกค้าสำหรับข้อมูลรับรอง OAuth 2.0 ที่กำหนดให้คลิกข้อความต่อไปนี้: เลือกข้อมูลรับรอง ในหน้าต่างที่เปิดขึ้นให้เลือกโครงการและข้อมูลรับรองที่คุณต้องการจากนั้นคลิก ดู

หรือดูรหัสลูกค้าและข้อมูลลับลูกค้าของคุณจาก หน้าข้อมูลรับรอง ใน API Console :

  1. Go to the Credentials page.
  2. คลิกที่ชื่อหนังสือรับรองของคุณหรือไอคอนดินสอ ( ) รหัสลูกค้าและความลับของคุณอยู่ที่ด้านบนของหน้า

ตั้งค่า URI การเปลี่ยนเส้นทาง

URI การเปลี่ยนเส้นทางที่คุณตั้งค่าไว้ใน API Console จะกำหนดที่ Google จะส่งการตอบกลับคำขอการตรวจสอบสิทธิ์ของคุณ

ในการสร้างดูหรือแก้ไข URIs การเปลี่ยนเส้นทางสำหรับข้อมูลรับรอง OAuth 2.0 ที่ระบุให้ทำดังต่อไปนี้:

  1. Go to the Credentials page.
  2. ในส่วน รหัสลูกค้า OAuth 2.0 ของหน้าคลิกข้อมูลรับรอง
  3. ดูหรือแก้ไข URIs การเปลี่ยนเส้นทาง

หากไม่มีส่วน รหัสลูกค้า OAuth 2.0 ในหน้าหนังสือรับรองแสดงว่าโครงการของคุณไม่มีข้อมูลรับรอง OAuth หากต้องการสร้างหนึ่งคลิก สร้างข้อมูลรับรอง

ปรับแต่งหน้าจอขอความยินยอมของผู้ใช้

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

หน้าจอคำยินยอมของผู้ใช้ยังแสดงข้อมูลการสร้างแบรนด์ เช่น ชื่อผลิตภัณฑ์ โลโก้ และ URL ของหน้าแรกด้วย คุณควบคุมข้อมูลการสร้างแบรนด์ใน API Console

วิธีเปิดใช้งานหน้าจอการยินยอมของโครงการ:

  1. เปิด Consent Screen page ใน Google API Console
  2. If prompted, select a project, or create a new one.
  3. กรอกแบบฟอร์มและคลิก บันทึก

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

ภาพหน้าจอของหน้าความยินยอม

การเข้าถึงบริการ

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

หากคุณเลือกไม่ใช้ไลบรารี ให้ทำตามวิธีการในส่วนที่เหลือของเอกสารนี้ ซึ่งอธิบายถึงโฟลว์คำขอ HTTP ที่อยู่ภายใต้ไลบรารีที่มีอยู่

กำลังตรวจสอบสิทธิ์ผู้ใช้

การตรวจสอบสิทธิ์ผู้ใช้เกี่ยวข้องกับการรับโทเค็นรหัสและตรวจสอบความถูกต้องของโทเค็นรหัส โทเค็น ID เป็นฟีเจอร์มาตรฐานของ OpenID Connect ที่ออกแบบมาเพื่อ แชร์การยืนยันข้อมูลประจำตัวบนอินเทอร์เน็ต

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

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

โฟลว์เซิร์ฟเวอร์

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

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

1. สร้างโทเค็นสถานะการป้องกันการปลอมแปลง

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

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

โค้ดต่อไปนี้สาธิตการสร้างโทเค็นของเซสชันที่ไม่ซ้ำกัน

PHP

คุณต้องดาวน์โหลดไลบรารีของไคลเอ็นต์ Google API สำหรับ PHP เพื่อใช้ตัวอย่างนี้

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
$state = bin2hex(random_bytes(128/8));
$app['session']->set('state', $state);
// Set the client ID, token state, and application name in the HTML while
// serving it.
return $app['twig']->render('index.html', array(
    'CLIENT_ID' => CLIENT_ID,
    'STATE' => $state,
    'APPLICATION_NAME' => APPLICATION_NAME
));

Java

คุณต้องดาวน์โหลดไลบรารีของไคลเอ็นต์ Google APIs สำหรับ Java เพื่อใช้ตัวอย่างนี้

// Create a state token to prevent request forgery.
// Store it in the session for later validation.
String state = new BigInteger(130, new SecureRandom()).toString(32);
request.session().attribute("state", state);
// Read index.html into memory, and set the client ID,
// token state, and application name in the HTML before serving it.
return new Scanner(new File("index.html"), "UTF-8")
    .useDelimiter("\\A").next()
    .replaceAll("[{]{2}\\s*CLIENT_ID\\s*[}]{2}", CLIENT_ID)
    .replaceAll("[{]{2}\\s*STATE\\s*[}]{2}", state)
    .replaceAll("[{]{2}\\s*APPLICATION_NAME\\s*[}]{2}",
    APPLICATION_NAME);

Python

คุณต้องดาวน์โหลดไลบรารีของไคลเอ็นต์ Google APIs สำหรับ Python เพื่อใช้ตัวอย่างนี้

# Create a state token to prevent request forgery.
# Store it in the session for later validation.
state = hashlib.sha256(os.urandom(1024)).hexdigest()
session['state'] = state
# Set the client ID, token state, and application name in the HTML while
# serving it.
response = make_response(
    render_template('index.html',
                    CLIENT_ID=CLIENT_ID,
                    STATE=state,
                    APPLICATION_NAME=APPLICATION_NAME))

2. ส่งคำขอตรวจสอบสิทธิ์ไปยัง Google

ขั้นตอนถัดไปคือการส่งคำขอ HTTPS GET ที่มีพารามิเตอร์ URI ที่เหมาะสม โปรดสังเกตการใช้ HTTPS แทน HTTP ในทุกขั้นตอนของกระบวนการนี้ โดยการเชื่อมต่อ HTTP จะถูกปฏิเสธ คุณควรเรียก URI ฐานจากเอกสาร Discovery โดยใช้ค่าข้อมูลเมตา authorization_endpoint การสนทนาต่อไปนี้จะถือว่า URI ฐานคือ https://accounts.google.com/o/oauth2/v2/auth

สำหรับคำขอพื้นฐาน ให้ระบุพารามิเตอร์ต่อไปนี้

  • client_id ซึ่งได้รับจาก API Console Credentials page
  • response_type ซึ่งในคำขอขั้นตอนรหัสการให้สิทธิ์พื้นฐานควรเป็น code (อ่านเพิ่มเติมที่ response_type)
  • scope ซึ่งในคำขอพื้นฐานควรเป็น openid email (อ่านเพิ่มเติมที่ scope)
  • redirect_uri ควรเป็นปลายทาง HTTP บนเซิร์ฟเวอร์ที่จะรับการตอบสนองจาก Google ค่าต้องตรงกับ URI การเปลี่ยนเส้นทางที่ได้รับอนุญาตสำหรับไคลเอ็นต์ OAuth 2.0 ซึ่งคุณกำหนดค่าไว้ใน API Console Credentials pageทุกประการ หากค่านี้ไม่ตรงกับ URI ที่ได้รับอนุญาต คำขอจะล้มเหลวโดยมีข้อผิดพลาด redirect_uri_mismatch
  • state ควรระบุค่าของโทเค็นเซสชันที่ไม่ซ้ำกันเพื่อป้องกันการปลอมแปลง รวมถึงข้อมูลอื่นๆ ที่จำเป็นในการกู้คืนบริบทเมื่อผู้ใช้กลับมาที่แอปพลิเคชันของคุณ เช่น URL เริ่มต้น (อ่านเพิ่มเติมที่ state)
  • nonce เป็นค่าแบบสุ่มที่แอปสร้างขึ้น ซึ่งจะเปิดใช้การป้องกันการเล่นซ้ำ หากมี
  • login_hint อาจเป็นอีเมลของผู้ใช้หรือสตริง sub ซึ่งเทียบเท่ากับรหัส Google ของผู้ใช้ หากคุณไม่ได้ระบุ login_hint และตอนนี้ผู้ใช้ลงชื่อเข้าสู่ระบบอยู่ หน้าจอคำยินยอมจะมีคำขอให้อนุมัติเพื่อปล่อยอีเมลของผู้ใช้ไปยังแอปของคุณ (ดูข้อมูลเพิ่มเติมที่ login_hint)
  • ใช้พารามิเตอร์ hd เพื่อเพิ่มประสิทธิภาพโฟลว์ OpenID Connect สำหรับผู้ใช้ในโดเมนหนึ่งๆ ที่เชื่อมโยงกับองค์กร Google Cloud (อ่านเพิ่มเติมที่ hd)

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

https://accounts.google.com/o/oauth2/v2/auth?
 response_type=code&
 client_id=424911365001.apps.googleusercontent.com&
 scope=openid%20email&
 redirect_uri=https%3A//oauth2.example.com/code&
 state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foauth2-login-demo.example.com%2FmyHome&
 login_hint=jsmith@example.com&
 nonce=0394852-3190485-2490358&
 hd=example.com

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

3. ยืนยันโทเค็นสถานะการป้องกันการปลอมแปลง

ระบบจะตอบกลับไปยัง redirect_uri ที่คุณระบุในคำขอ คำตอบทั้งหมดจะแสดงในสตริงคำค้นหา ดังที่แสดงด้านล่าง

https://oauth2.example.com/code?state=security_token%3D138r5719ru3e1%26url%3Dhttps%3A%2F%2Foa2cb.example.com%2FmyHome&code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7&scope=openid%20email%20https://www.googleapis.com/auth/userinfo.email

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

โค้ดต่อไปนี้แสดงถึงการยืนยันโทเค็นของเซสชันที่คุณสร้างในขั้นตอนที่ 1

PHP

คุณต้องดาวน์โหลดไลบรารีของไคลเอ็นต์ Google API สำหรับ PHP เพื่อใช้ตัวอย่างนี้

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
  return new Response('Invalid state parameter', 401);
}

Java

คุณต้องดาวน์โหลดไลบรารีของไคลเอ็นต์ Google APIs สำหรับ Java เพื่อใช้ตัวอย่างนี้

// Ensure that there is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if (!request.queryParams("state").equals(
    request.session().attribute("state"))) {
  response.status(401);
  return GSON.toJson("Invalid state parameter.");
}

Python

คุณต้องดาวน์โหลดไลบรารีของไคลเอ็นต์ Google APIs สำหรับ Python เพื่อใช้ตัวอย่างนี้

# Ensure that the request is not a forgery and that the user sending
# this connect request is the expected user.
if request.args.get('state', '') != session['state']:
  response = make_response(json.dumps('Invalid state parameter.'), 401)
  response.headers['Content-Type'] = 'application/json'
  return response

4. แลกเปลี่ยน code เพื่อรับโทเค็นเพื่อการเข้าถึงและโทเค็นรหัส

การตอบกลับจะมีพารามิเตอร์ code ซึ่งเป็นรหัสการให้สิทธิ์แบบใช้ครั้งเดียวที่เซิร์ฟเวอร์แลกเปลี่ยนกับโทเค็นเพื่อการเข้าถึงและโทเค็นรหัสได้ เซิร์ฟเวอร์ของคุณสร้างการแลกเปลี่ยนนี้ด้วยการส่งคำขอ HTTPS POST ระบบจะส่งคำขอ POST ไปยังปลายทางของโทเค็น ซึ่งคุณควรเรียกข้อมูลจากเอกสาร Discovery โดยใช้ค่าข้อมูลเมตา token_endpoint การสนทนาต่อไปนี้จะถือว่าปลายทางคือ https://oauth2.googleapis.com/token คำขอต้องมีพารามิเตอร์ต่อไปนี้ในเนื้อหา POST

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

คำขอจริงอาจมีลักษณะเหมือนตัวอย่างต่อไปนี้

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

การตอบกลับคำขอที่สำเร็จนี้มีช่องต่อไปนี้ในอาร์เรย์ JSON

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

ช่องนี้จะปรากฏต่อเมื่อตั้งค่าพารามิเตอร์ access_type เป็น offline ในคำขอการตรวจสอบสิทธิ์ โปรดดูรายละเอียดที่หัวข้อรีเฟรชโทเค็น

5. รับข้อมูลผู้ใช้จากโทเค็นรหัส

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

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

เพย์โหลดของโทเค็นรหัส

โทเค็นรหัสคือออบเจ็กต์ JSON ที่มีชุดคู่ของชื่อ/ค่า ต่อไปนี้เป็นตัวอย่างที่มีการจัดรูปแบบเพื่อให้อ่านได้ง่าย

{
  "iss": "https://accounts.google.com",
  "azp": "1234987819200.apps.googleusercontent.com",
  "aud": "1234987819200.apps.googleusercontent.com",
  "sub": "10769150350006150715113082367",
  "at_hash": "HK6E_P6Dh8Y93mRNtsDB1Q",
  "hd": "example.com",
  "email": "jsmith@example.com",
  "email_verified": "true",
  "iat": 1353601026,
  "exp": 1353604926,
  "nonce": "0394852-3190485-2490358"
}

โทเค็นรหัส Google อาจมีช่องต่อไปนี้ (เรียกว่าการอ้างสิทธิ์)

การอ้างสิทธิ์ ระบุแล้ว คำอธิบาย
aud ทุกครั้ง กลุ่มเป้าหมายที่เป็นกลุ่มเป้าหมายของโทเค็นรหัสนี้ ซึ่งต้องเป็นหนึ่งในรหัสไคลเอ็นต์ OAuth 2.0 ของแอปพลิเคชัน
exp ทุกครั้ง เวลาหมดอายุในวันที่หรือหลังจากนั้น โทเค็นรหัสต้องไม่ได้รับการยอมรับ แสดงเป็นเวลา Unix (วินาทีที่เป็นจำนวนเต็ม)
iat ทุกครั้ง เวลาที่ออกโทเค็นรหัส แสดงเป็นเวลา Unix (วินาทีที่เป็นจำนวนเต็ม)
iss ทุกครั้ง ตัวระบุผู้ออกบัตรสำหรับผู้ออกบัตร https://accounts.google.com หรือ accounts.google.com เสมอสําหรับโทเค็นรหัส Google
sub ทุกครั้ง ตัวระบุผู้ใช้จะไม่ซ้ำกันในบัญชี Google ทั้งหมด และไม่มีการนํามาใช้ใหม่ บัญชี Google บัญชีหนึ่งมีอีเมลได้หลายรายการในช่วงเวลาต่างๆ แต่ค่า sub จะไม่เปลี่ยนแปลง ใช้ sub ภายในแอปพลิเคชันเป็นคีย์ตัวระบุที่ไม่ซ้ำกันสำหรับผู้ใช้ มีความยาวสูงสุด 255 อักขระ ASCII คำนึงถึงตัวพิมพ์เล็กหรือใหญ่
at_hash แฮชโทเค็นเพื่อการเข้าถึง ระบุการตรวจสอบว่าโทเค็นเพื่อการเข้าถึงเชื่อมโยงกับโทเค็นข้อมูลประจำตัวแล้ว หากโทเค็นรหัสออกที่มีค่า access_token ในขั้นตอนของเซิร์ฟเวอร์ การอ้างสิทธิ์นี้ก็จะรวมอยู่ด้วยเสมอ การอ้างสิทธิ์นี้ใช้เป็นกลไกสำรองเพื่อป้องกันการโจมตีด้วยการปลอมแปลงคำขอข้ามเว็บไซต์ได้ แต่หากทำตามขั้นตอนที่ 1 และขั้นตอนที่ 3 ก็ไม่จำเป็นต้องยืนยันโทเค็นเพื่อการเข้าถึง
azp client_id ของผู้นำเสนอที่ได้รับอนุญาต การอ้างสิทธิ์นี้จำเป็นต่อเมื่อบุคคลที่ขอโทเค็นรหัสไม่ใช่บุคคลเดียวกับกลุ่มเป้าหมายของโทเค็นรหัส ซึ่งอาจเกิดขึ้นกับ Google สำหรับแอปแบบผสมที่เว็บแอปพลิเคชันและแอป Android มี OAuth 2.0 ต่างกันclient_id แต่แชร์โปรเจ็กต์ Google APIs เดียวกัน
email อีเมลของผู้ใช้ ค่านี้อาจซ้ำกับผู้ใช้รายนี้และไม่เหมาะกับการใช้เป็นคีย์หลัก ระบุเฉพาะเมื่อขอบเขตมีค่าขอบเขต email
email_verified เป็นจริงหากอีเมลของผู้ใช้ได้รับการยืนยันแล้ว มิเช่นนั้นให้เป็นเท็จ
family_name นามสกุลของผู้ใช้ อาจแสดงเมื่อมีการอ้างสิทธิ์ name
given_name ชื่อจริงของผู้ใช้ อาจแสดงเมื่อมีการอ้างสิทธิ์ name
hd โดเมนที่เชื่อมโยงกับองค์กร Google Cloud ของผู้ใช้ ระบุเฉพาะในกรณีที่ผู้ใช้อยู่ในองค์กร Google Cloud
locale ภาษาของผู้ใช้ ซึ่งแสดงโดยแท็กภาษา BCP 47 อาจแสดงเมื่อมีการอ้างสิทธิ์ name
name ชื่อเต็มของผู้ใช้ในแบบฟอร์มที่แสดงได้ อาจมีการให้บริการในกรณีต่อไปนี้
  • ขอบเขตคำขอมีสตริง "profile"
  • โทเค็นรหัสจะแสดงจากการรีเฟรชโทเค็น

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

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

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

profile URL หน้าโปรไฟล์ของผู้ใช้ อาจมีการให้บริการในกรณีต่อไปนี้
  • ขอบเขตคำขอมีสตริง "profile"
  • โทเค็นรหัสจะแสดงจากการรีเฟรชโทเค็น

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

6. ตรวจสอบสิทธิ์ผู้ใช้

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

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

หัวข้อขั้นสูง

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

การเข้าถึง Google API อื่นๆ

ข้อดีอย่างหนึ่งของการใช้ OAuth 2.0 สำหรับการตรวจสอบสิทธิ์คือแอปพลิเคชันของคุณจะได้รับสิทธิ์ให้ใช้ Google API อื่นๆ ในนามของผู้ใช้ (เช่น YouTube, Google ไดรฟ์, ปฏิทิน หรือ Contacts) ได้ในเวลาเดียวกันเมื่อคุณตรวจสอบสิทธิ์ผู้ใช้ ซึ่งทำได้โดยการรวมขอบเขตอื่นๆ ที่ต้องการไว้ในคำขอการตรวจสอบสิทธิ์ที่ส่งให้ Google ตัวอย่างเช่น หากต้องการเพิ่มกลุ่มอายุของผู้ใช้ในคำขอตรวจสอบสิทธิ์ ให้ส่งพารามิเตอร์ขอบเขต openid email https://www.googleapis.com/auth/profile.agerange.read ในหน้าจอขอความยินยอม ระบบจะแจ้งผู้ใช้อย่างเหมาะสม โทเค็นเพื่อการเข้าถึงที่คุณได้รับจาก Google จะช่วยให้คุณเข้าถึง API ทั้งหมดที่เกี่ยวข้องกับขอบเขตการเข้าถึงที่คุณขอและได้รับอนุญาต

รีเฟรชโทเค็น

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

ข้อควรพิจารณา

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

ดูข้อมูลเพิ่มเติมได้ที่การรีเฟรชโทเค็นเพื่อการเข้าถึง (การเข้าถึงแบบออฟไลน์)

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

ดูข้อมูลเพิ่มเติมเกี่ยวกับพารามิเตอร์ prompt ได้ที่ prompt ในตารางพารามิเตอร์ URI การตรวจสอบสิทธิ์

พารามิเตอร์ URI การตรวจสอบสิทธิ์

ตารางต่อไปนี้อธิบายพารามิเตอร์ที่ครบถ้วนยิ่งขึ้นที่ API การตรวจสอบสิทธิ์ OAuth 2.0 ของ Google ยอมรับ

พารามิเตอร์ ต้องระบุ คำอธิบาย
client_id (ต้องระบุ) สตริงรหัสไคลเอ็นต์ที่คุณได้รับจาก Credentials page API Consoleตามที่อธิบายไว้ในรับข้อมูลเข้าสู่ระบบ OAuth 2.0
nonce (ต้องระบุ) ค่าแบบสุ่มที่แอปสร้างขึ้นซึ่งเปิดใช้การป้องกันการเล่นซ้ำ
response_type (ต้องระบุ) หากค่าคือ code จะเปิดใช้ขั้นตอนการใช้รหัสการให้สิทธิ์พื้นฐาน ซึ่งต้องใช้ POST กับปลายทางของโทเค็นเพื่อรับโทเค็น หากค่าคือ token id_token หรือ id_token token จะเปิดใช้โฟลว์แบบโดยนัย ซึ่งต้องใช้ JavaScript ที่ URI การเปลี่ยนเส้นทางเพื่อดึงโทเค็นจากตัวระบุ #fragment ของ URI
redirect_uri (ต้องระบุ) กำหนดว่าจะส่งคำตอบไปที่ใด ค่าของพารามิเตอร์นี้ต้องตรงกับค่าการเปลี่ยนเส้นทางที่ได้รับอนุญาตค่าใดค่าหนึ่งที่คุณตั้งไว้ใน API Console Credentials page (รวมถึงสคีม HTTP หรือ HTTPS, ตัวพิมพ์ และเครื่องหมาย "/" ต่อท้าย หากมี)
scope (ต้องระบุ)

พารามิเตอร์ขอบเขตต้องขึ้นต้นด้วยค่า openid จากนั้นรวมค่า profile ค่า email หรือทั้ง 2 อย่าง

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

หากมีค่าขอบเขต email โทเค็นรหัสจะมีการอ้างสิทธิ์ email และ email_verified

นอกเหนือจากขอบเขตเฉพาะ OpenID เหล่านี้แล้ว อาร์กิวเมนต์ขอบเขตยังใส่ค่าขอบเขตอื่นๆ ได้ด้วย ค่าขอบเขตทั้งหมดต้องคั่นด้วยการเว้นวรรค ตัวอย่างเช่น หากต้องการเข้าถึง Google ไดรฟ์ของผู้ใช้ในแต่ละไฟล์ พารามิเตอร์ขอบเขตอาจเป็น openid profile email https://www.googleapis.com/auth/drive.file

โปรดดูข้อมูลเกี่ยวกับขอบเขตที่พร้อมใช้งานที่หัวข้อขอบเขต OAuth 2.0 สำหรับ Google APIs หรือเอกสารสำหรับ Google API ที่คุณต้องการใช้

state (ไม่บังคับ แต่แนะนำอย่างยิ่ง)

สตริงทึบที่มีวงกลมล้อมรอบในโปรโตคอล กล่าวคือ แสดงผลเป็นพารามิเตอร์ URI ในโฟลว์พื้นฐาน และในตัวระบุ URI #fragment ในโฟลว์แบบไม่เจาะจงปลายทาง

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

access_type (ไม่บังคับ) ค่าที่อนุญาตคือ offline และ online เอฟเฟกต์ จะบันทึกไว้ในการเข้าถึงแบบออฟไลน์ หากมีการขอโทเค็นเพื่อการเข้าถึง ไคลเอ็นต์จะไม่ได้รับโทเค็นการรีเฟรชเว้นแต่จะระบุค่า offline ไว้
display (ไม่บังคับ) ค่าสตริง ASCII เพื่อใช้ระบุวิธีที่เซิร์ฟเวอร์การให้สิทธิ์แสดงหน้าอินเทอร์เฟซผู้ใช้สำหรับการตรวจสอบสิทธิ์และความยินยอม ค่าต่อไปนี้มีการระบุและได้รับการยอมรับโดยเซิร์ฟเวอร์ของ Google แต่ไม่ได้ส่งผลกระทบต่อลักษณะการทำงานของค่าดังกล่าว: page, popup, touch และ wap
hd (ไม่บังคับ)

ปรับปรุงกระบวนการเข้าสู่ระบบสำหรับบัญชีที่องค์กร Google Cloud เป็นเจ้าของ การรวมโดเมนองค์กรของ Google Cloud (เช่น mycollege.edu) จะทำให้ระบุได้ว่าควรเพิ่มประสิทธิภาพ UI การเลือกบัญชีสำหรับบัญชีในโดเมนดังกล่าว หากต้องการเพิ่มประสิทธิภาพบัญชีขององค์กร Google Cloud โดยทั่วไปแทนที่จะสร้างโดเมนองค์กรของ Google Cloud เพียงโดเมนเดียว ให้ตั้งค่าเครื่องหมายดอกจัน (*) ดังนี้ hd=*

อย่าอาศัยการเพิ่มประสิทธิภาพ UI นี้เพื่อควบคุมผู้ที่เข้าถึงแอปของคุณได้ เนื่องจากคำขอฝั่งไคลเอ็นต์จะแก้ไขได้ อย่าลืมvalidateว่าโทเค็นรหัสที่ส่งคืนมีค่าการอ้างสิทธิ์ hd ที่ตรงกับสิ่งที่คุณคาดหวัง (เช่น mycolledge.edu) การอ้างสิทธิ์โทเค็นรหัส hd อยู่ภายในโทเค็นความปลอดภัยจาก Google จึงทำให้ค่าเชื่อถือได้ ซึ่งต่างจากพารามิเตอร์คำขอ

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

โปรดทราบว่าคุณให้สิทธิ์เพิ่มเติมกับขั้นตอนแอปที่ติดตั้งไม่ได้

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

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

  • consent

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

  • select_account

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

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

การตรวจสอบโทเค็นรหัส

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

สถานการณ์ทั่วไปที่คุณอาจส่งโทเค็นรหัสไปยังเซิร์ฟเวอร์มีดังนี้

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

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

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

การตรวจสอบโทเค็นรหัสมีหลายขั้นตอน ดังนี้

  1. ตรวจสอบว่าโทเค็นรหัสได้รับการลงนามอย่างถูกต้องโดยผู้ออก โทเค็นที่ออกโดย Google จะได้รับการลงนามโดยใช้ใบรับรองรายการใดรายการหนึ่งที่พบใน URI ที่ระบุไว้ในค่าข้อมูลเมตา jwks_uri ของเอกสารการค้นพบ
  2. ตรวจสอบว่าค่าของการอ้างสิทธิ์ iss ในโทเค็นรหัสเท่ากับ https://accounts.google.com หรือ accounts.google.com
  3. ตรวจสอบว่าค่าการอ้างสิทธิ์ aud ในโทเค็นรหัสเท่ากับรหัสไคลเอ็นต์ของแอป
  4. ตรวจสอบว่าเวลาหมดอายุ (การอ้างสิทธิ์ exp รายการ) ของโทเค็นรหัสยังไม่ผ่าน
  5. หากคุณระบุค่าพารามิเตอร์ hd ในคำขอ ให้ยืนยันว่าโทเค็นรหัสมีการอ้างสิทธิ์ hd ที่ตรงกับโดเมนที่ยอมรับซึ่งเชื่อมโยงกับองค์กร Google Cloud

ขั้นตอนที่ 2 ถึง 5 จะมีเฉพาะการเปรียบเทียบสตริงและวันที่ซึ่งค่อนข้างตรงไปตรงมา ดังนั้นเราจึงไม่ได้อธิบายรายละเอียดในส่วนนี้

โดยขั้นตอนแรกจะซับซ้อนมากขึ้นและเกี่ยวข้องกับการตรวจสอบลายเซ็นที่เข้ารหัส สำหรับวัตถุประสงค์การแก้ไขข้อบกพร่อง คุณจะใช้ปลายทาง tokeninfo ของ Google เพื่อเปรียบเทียบกับการประมวลผลในเครื่องที่นำมาใช้ในเซิร์ฟเวอร์หรืออุปกรณ์ได้ สมมติว่าค่าของโทเค็นรหัสคือ XYZ123 จากนั้นจะต้องยกเลิกการอ้างอิง URI https://oauth2.googleapis.com/tokeninfo?id_token=XYZ123 หากลายเซ็นโทเค็นถูกต้อง การตอบกลับจะเป็นเพย์โหลด JWT ในรูปแบบออบเจ็กต์ JSON ที่ถอดรหัสแล้ว

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

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

การรับข้อมูลโปรไฟล์ผู้ใช้

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

  1. คุณต้องใส่ค่าขอบเขต openid profile ในคำขอการตรวจสอบสิทธิ์เพื่อให้เป็นไปตามข้อกำหนดของ OpenID

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

    scope=openid%20profile%20email
  2. เพิ่มโทเค็นเพื่อการเข้าถึงไปยังส่วนหัวการให้สิทธิ์ และส่งคำขอ HTTPS GET ไปยังปลายทาง userinfo ซึ่งคุณควรเรียกดูจากเอกสาร Discovery โดยใช้ค่าข้อมูลเมตา userinfo_endpoint คำตอบของ Userinfo จะมีข้อมูลเกี่ยวกับผู้ใช้ตามที่อธิบายไว้ใน OpenID Connect Standard Claims และค่าข้อมูลเมตา claims_supported ของเอกสาร Discovery ผู้ใช้หรือองค์กรของผู้ใช้อาจเลือกที่จะระบุหรือระงับบางช่อง คุณจึงอาจไม่ได้รับข้อมูลของทุกช่องสำหรับขอบเขตการเข้าถึงที่ได้รับอนุญาต

เอกสารการค้นพบ

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

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

https://accounts.google.com/.well-known/openid-configuration

หากต้องการใช้บริการ OpenID Connect ของ Google คุณควรฮาร์ดโค้ด URI เอกสารการค้นพบ (https://accounts.google.com/.well-known/openid-configuration) ลงในแอปพลิเคชันของคุณ แอปพลิเคชันจะดึงข้อมูลเอกสาร ใช้กฎการแคชในการตอบสนอง จากนั้นดึง URI ปลายทางจากเอกสารตามความจำเป็น เช่น ในการตรวจสอบสิทธิ์ผู้ใช้ โค้ดจะดึงค่าข้อมูลเมตา authorization_endpoint (https://accounts.google.com/o/oauth2/v2/auth ในตัวอย่างด้านล่าง) เป็น URI ฐานสำหรับคำขอการตรวจสอบสิทธิ์ที่ส่งไปยัง Google

ต่อไปนี้เป็นตัวอย่างเอกสารดังกล่าว ชื่อช่องคือชื่อที่ระบุใน OpenID Connect Discovery 1.0 (โปรดดูความหมายของชื่อในเอกสารดังกล่าว) ค่าต่างๆ เป็นเพียงการอธิบายเท่านั้นและอาจมีการเปลี่ยนแปลง แม้ว่าจะคัดลอกมาจากเอกสาร Google Discovery ฉบับจริงล่าสุดก็ตาม

{
  "issuer": "https://accounts.google.com",
  "authorization_endpoint": "https://accounts.google.com/o/oauth2/v2/auth",
  "device_authorization_endpoint": "https://oauth2.googleapis.com/device/code",
  "token_endpoint": "https://oauth2.googleapis.com/token",
  "userinfo_endpoint": "https://openidconnect.googleapis.com/v1/userinfo",
  "revocation_endpoint": "https://oauth2.googleapis.com/revoke",
  "jwks_uri": "https://www.googleapis.com/oauth2/v3/certs",
  "response_types_supported": [
    "code",
    "token",
    "id_token",
    "code token",
    "code id_token",
    "token id_token",
    "code token id_token",
    "none"
  ],
  "subject_types_supported": [
    "public"
  ],
  "id_token_signing_alg_values_supported": [
    "RS256"
  ],
  "scopes_supported": [
    "openid",
    "email",
    "profile"
  ],
  "token_endpoint_auth_methods_supported": [
    "client_secret_post",
    "client_secret_basic"
  ],
  "claims_supported": [
    "aud",
    "email",
    "email_verified",
    "exp",
    "family_name",
    "given_name",
    "iat",
    "iss",
    "locale",
    "name",
    "picture",
    "sub"
  ],
  "code_challenge_methods_supported": [
    "plain",
    "S256"
  ]
}

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

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

ไลบรารีของไคลเอ็นต์ต่อไปนี้ช่วยให้การใช้ OAuth 2.0 ทำได้ง่ายขึ้นโดยการผสานรวมกับเฟรมเวิร์กยอดนิยม

การปฏิบัติตามข้อกำหนดของ OpenID Connect

ระบบการตรวจสอบสิทธิ์ OAuth 2.0 ของ Google รองรับฟีเจอร์ที่จำเป็นของข้อมูลจำเพาะของ OpenID Connect Core ไคลเอ็นต์ที่ออกแบบมาให้ทำงานร่วมกับ OpenID Connect ควรทำงานร่วมกับบริการนี้ได้ (ยกเว้นออบเจ็กต์คำขอ OpenID)