หากอัปเกรดเป็น Firebase Authentication with Identity Platform คุณสามารถเพิ่มการตรวจสอบสิทธิ์แบบหลายปัจจัย (MFA) ด้วยรหัสผ่านแบบใช้ครั้งเดียวตามเวลา (TOTP) ลงในแอปได้
Firebase Authentication with Identity Platform ช่วยให้คุณใช้ TOTP เป็นปัจจัยเพิ่มเติมสำหรับการทำ MFA ได้ เมื่อเปิดใช้ฟีเจอร์นี้ ผู้ใช้ที่พยายามลงชื่อเข้าใช้แอปจะเห็นคำขอ TOTP โดยผู้ใช้ต้องใช้แอป Authenticator ที่สร้างรหัส TOTP ที่ถูกต้องได้ เช่น Google Authenticator
ก่อนเริ่มต้น
เปิดใช้ผู้ให้บริการอย่างน้อย 1 รายที่รองรับ MFA โปรดทราบว่าผู้ให้บริการทั้งหมด ยกเว้น ผู้ให้บริการต่อไปนี้รองรับ MFA
- การตรวจสอบสิทธิ์ทางโทรศัพท์
- การตรวจสอบสิทธิ์แบบไม่ระบุชื่อ
- โทเค็นการตรวจสอบสิทธิ์ที่กำหนดเอง
- Apple Game Center
ตรวจสอบว่าแอปของคุณยืนยันที่อยู่อีเมลของผู้ใช้ MFA กำหนดให้มีการยืนยันทางอีเมล ซึ่งจะป้องกันไม่ให้ผู้ไม่ประสงค์ดีลงทะเบียนใช้บริการด้วยที่อยู่อีเมลที่ไม่ใช่ของตนเอง แล้วล็อกไม่ให้เจ้าของที่อยู่อีเมลตัวจริงเข้าถึงบัญชีโดยการเพิ่มปัจจัยที่ 2
ติดตั้ง Firebase JavaScript SDK หากยังไม่ได้ดำเนินการ
ระบบรองรับ TOTP MFA ใน Web SDK แบบโมดูลาร์ เวอร์ชัน v9.19.1 ขึ้นไปเท่านั้น
เปิดใช้ TOTP MFA
หากต้องการเปิดใช้ TOTP เป็นปัจจัยที่ 2 ให้ใช้ Admin SDK หรือเรียกใช้ปลายทาง REST ของการกำหนดค่าโปรเจ็กต์
หากต้องการใช้ Admin SDK ให้ทำดังนี้
ติดตั้ง Firebase Admin Node.js SDK หากยังไม่ได้ดำเนินการ
ระบบรองรับ TOTP MFA ใน Firebase Admin Node.js SDK เวอร์ชัน 11.6.0 ขึ้นไปเท่านั้น
เรียกใช้คำสั่งต่อไปนี้
import { getAuth } from 'firebase-admin/auth'; getAuth().projectConfigManager().updateProjectConfig( { multiFactorConfig: { providerConfigs: [{ state: "ENABLED", totpProviderConfig: { adjacentIntervals: NUM_ADJ_INTERVALS } }] } })แทนที่ข้อมูลต่อไปนี้
NUM_ADJ_INTERVALS: จำนวนช่วงเวลาที่อยู่ติดกันซึ่งจะยอมรับ TOTP โดยมีค่าตั้งแต่ 0 ถึง 10 ค่าเริ่มต้นคือ 5TOTP ทำงานโดยตรวจสอบว่าเมื่อทั้ง 2 ฝ่าย (ผู้พิสูจน์และผู้ตรวจสอบ) สร้าง OTP ภายในช่วงเวลาเดียวกัน (โดยปกติคือ 30 วินาที) ทั้ง 2 ฝ่ายจะสร้างรหัสผ่านเดียวกัน อย่างไรก็ตาม คุณสามารถกำหนดค่าบริการ TOTP ให้ยอมรับ TOTP จากช่วงเวลาที่อยู่ติดกันได้ด้วย เพื่อรองรับความคลาดเคลื่อนของนาฬิกาในอุปกรณ์ของทั้ง 2 ฝ่ายและเวลาตอบสนองของมนุษย์
หากต้องการเปิดใช้ TOTP MFA โดยใช้ REST API ให้เรียกใช้คำสั่งต่อไปนี้
curl -X PATCH "https://identitytoolkit.googleapis.com/admin/v2/projects/PROJECT_ID/config?updateMask=mfa" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-H "X-Goog-User-Project: PROJECT_ID" \
-d \
'{
"mfa": {
"providerConfigs": [{
"state": "ENABLED",
"totpProviderConfig": {
"adjacentIntervals": NUM_ADJ_INTERVALS
}
}]
}
}'
แทนที่ข้อมูลต่อไปนี้
PROJECT_ID: รหัสโปรเจ็กต์NUM_ADJ_INTERVALS: จำนวนช่วงเวลา โดยมีค่าตั้งแต่ 0 ถึง 10 ค่าเริ่มต้นคือ 5TOTP ทำงานโดยตรวจสอบว่าเมื่อทั้ง 2 ฝ่าย (ผู้พิสูจน์และผู้ตรวจสอบ) สร้าง OTP ภายในช่วงเวลาเดียวกัน (โดยปกติคือ 30 วินาที) ทั้ง 2 ฝ่ายจะสร้างรหัสผ่านเดียวกัน อย่างไรก็ตาม คุณสามารถกำหนดค่าบริการ TOTP ให้ยอมรับ TOTP จากช่วงเวลาที่อยู่ติดกันได้ด้วย เพื่อรองรับความคลาดเคลื่อนของนาฬิกาในอุปกรณ์ของทั้ง 2 ฝ่ายและเวลาตอบสนองของมนุษย์
เลือกรูปแบบการลงทะเบียน
คุณสามารถเลือกว่าแอปของคุณกำหนดให้มีการตรวจสอบสิทธิ์แบบหลายปัจจัยหรือไม่ รวมถึงวิธีและเวลาในการลงทะเบียนผู้ใช้ รูปแบบที่ใช้กันโดยทั่วไปมีดังนี้
ลงทะเบียนปัจจัยที่ 2 ของผู้ใช้เป็นส่วนหนึ่งของการลงทะเบียน ใช้วิธีนี้หากแอปของคุณกำหนดให้ผู้ใช้ทุกคนต้องมีการตรวจสอบสิทธิ์แบบหลายปัจจัย
เสนอตัวเลือกที่ข้ามได้เพื่อลงทะเบียนปัจจัยที่ 2 ระหว่างการลงทะเบียน หากต้องการสนับสนุนแต่ไม่กำหนดให้มีการตรวจสอบสิทธิ์แบบหลายปัจจัยในแอป คุณอาจใช้วิธีนี้
ให้ความสามารถในการเพิ่มปัจจัยที่ 2 จากบัญชีของผู้ใช้หรือหน้าการจัดการโปรไฟล์ แทนที่จะเป็นหน้าจอลงชื่อสมัครใช้ วิธีนี้จะช่วยลดความยุ่งยากในระหว่างกระบวนการลงทะเบียน ขณะเดียวกันก็ยังคงให้ผู้ใช้ที่ให้ความสำคัญกับความปลอดภัยสามารถใช้การตรวจสอบสิทธิ์แบบหลายปัจจัยได้
กำหนดให้เพิ่มปัจจัยที่ 2 ทีละรายการเมื่อผู้ใช้ต้องการเข้าถึงฟีเจอร์ที่มีข้อกำหนดด้านความปลอดภัยที่เข้มงวดขึ้น
ลงทะเบียนผู้ใช้ใน TOTP MFA
หลังจากเปิดใช้ TOTP MFA เป็นปัจจัยที่ 2 สำหรับแอปแล้ว ให้ใช้ตรรกะฝั่งไคลเอ็นต์เพื่อลงทะเบียนผู้ใช้ใน TOTP MFA โดยทำดังนี้
นำเข้าคลาสและฟังก์ชัน MFA ที่จำเป็น
import { multiFactor, TotpMultiFactorGenerator, TotpSecret, getAuth, } from "firebase/auth";ตรวจสอบสิทธิ์ผู้ใช้อีกครั้ง
สร้างข้อมูลลับ TOTP สำหรับผู้ใช้ที่ผ่านการตรวจสอบสิทธิ์แล้ว
// Generate a TOTP secret. const multiFactorSession = await multiFactor(currentUser).getSession(); const totpSecret = await TotpMultiFactorGenerator.generateSecret( multiFactorSession );แสดงข้อมูลลับแก่ผู้ใช้และแจ้งให้ผู้ใช้ป้อนข้อมูลลับดังกล่าวลงในแอป Authenticator
แอป Authenticator หลายแอปช่วยให้ผู้ใช้เพิ่มข้อมูลลับ TOTP ใหม่ได้อย่างรวดเร็วโดยการ สแกนคิวอาร์โค้ดที่แสดง URI ของคีย์ที่เข้ากันได้กับ Google Authenticator หากต้องการสร้างคิวอาร์โค้ดเพื่อวัตถุประสงค์นี้ ให้สร้าง URI ด้วย
generateQrCodeUrl()แล้วเข้ารหัสโดยใช้ไลบรารีคิวอาร์โค้ดที่คุณเลือก เช่นconst totpUri = totpSecret.generateQrCodeUrl( currentUser.email, "Your App's Name" ); await QRExampleLib.toCanvas(totpUri, qrElement);ไม่ว่าคุณจะแสดงคิวอาร์โค้ดหรือไม่ก็ตาม ให้แสดงคีย์ลับเสมอเพื่อรองรับแอป Authenticator ที่อ่านคิวอาร์โค้ดไม่ได้
// Also display this key: const secret = totpSecret.secretKey;หลังจากผู้ใช้เพิ่มข้อมูลลับลงในแอป Authenticator แล้ว แอปจะเริ่มสร้าง TOTP
แจ้งให้ผู้ใช้พิมพ์ TOTP ที่แสดงในแอป Authenticator และใช้ TOTP ดังกล่าวเพื่อลงทะเบียน MFA ให้เสร็จสมบูรณ์
// Ask the user for a verification code from the authenticator app. const verificationCode = // Code from user input. // Finalize the enrollment. const multiFactorAssertion = TotpMultiFactorGenerator.assertionForEnrollment( totpSecret, verificationCode ); await multiFactor(currentUser).enroll(multiFactorAssertion, mfaDisplayName);
ลงชื่อเข้าใช้ผู้ใช้ด้วยปัจจัยที่ 2
หากต้องการลงชื่อเข้าใช้ผู้ใช้ด้วย TOTP MFA ให้ใช้โค้ดต่อไปนี้
นำเข้าคลาสและฟังก์ชัน MFA ที่จำเป็น
import { getAuth, getMultiFactorResolver, TotpMultiFactorGenerator, } from "firebase/auth";เรียกใช้เมธอด
signInWith- เมธอดใดเมธอดหนึ่งเช่นเดียวกับที่คุณจะทำหากไม่ได้ใช้ MFA (เช่นsignInWithEmailAndPassword()) หากเมธอดแสดงข้อผิดพลาดauth/multi-factor-auth-requiredให้เริ่มขั้นตอน MFA ของแอปtry { const userCredential = await signInWithEmailAndPassword( getAuth(), email, password ); // If the user is not enrolled with a second factor and provided valid // credentials, sign-in succeeds. // (If your app requires MFA, this could be considered an error // condition, which you would resolve by forcing the user to enroll a // second factor.) // ... } catch (error) { switch (error.code) { case "auth/multi-factor-auth-required": // Initiate your second factor sign-in flow. (See next step.) // ... break; case ...: // Handle other errors, such as wrong passwords. break; } }ขั้นตอน MFA ของแอปควรแจ้งให้ผู้ใช้เลือกปัจจัยที่ 2 ที่ต้องการใช้ก่อน คุณดูรายการปัจจัยที่ 2 ที่รองรับได้โดยตรวจสอบพร็อพเพอร์ตี้
hintsของอินสแตนซ์MultiFactorResolverconst mfaResolver = getMultiFactorResolver(getAuth(), error); const enrolledFactors = mfaResolver.hints.map(info => info.displayName);หากผู้ใช้เลือกใช้ TOTP ให้แจ้งให้ผู้ใช้พิมพ์ TOTP ที่แสดงในแอป Authenticator และใช้ TOTP ดังกล่าวเพื่อลงชื่อเข้าใช้
switch (mfaResolver.hints[selectedIndex].factorId) { case TotpMultiFactorGenerator.FACTOR_ID: const otpFromAuthenticator = // OTP typed by the user. const multiFactorAssertion = TotpMultiFactorGenerator.assertionForSignIn( mfaResolver.hints[selectedIndex].uid, otpFromAuthenticator ); try { const userCredential = await mfaResolver.resolveSignIn( multiFactorAssertion ); // Successfully signed in! } catch (error) { // Invalid or expired OTP. } break; case PhoneMultiFactorGenerator.FACTOR_ID: // Handle SMS second factor. break; default: // Unsupported second factor? break; }
ยกเลิกการลงทะเบียนจาก TOTP MFA
ส่วนนี้อธิบายวิธีจัดการเมื่อผู้ใช้ยกเลิกการลงทะเบียนจาก TOTP MFA
หากผู้ใช้ลงชื่อสมัครใช้ตัวเลือก MFA หลายรายการ และยกเลิกการลงทะเบียนจากตัวเลือกที่เปิดใช้ล่าสุด ผู้ใช้จะได้รับข้อผิดพลาด auth/user-token-expired และออกจากระบบ ผู้ใช้ต้องลงชื่อเข้าใช้อีกครั้งและยืนยันข้อมูลเข้าสู่ระบบที่มีอยู่ เช่น ที่อยู่อีเมลและรหัสผ่าน
หากต้องการยกเลิกการลงทะเบียนผู้ใช้ จัดการข้อผิดพลาด และทริกเกอร์การตรวจสอบสิทธิ์อีกครั้ง ให้ใช้โค้ดต่อไปนี้
import {
EmailAuthProvider,
TotpMultiFactorGenerator,
getAuth,
multiFactor,
reauthenticateWithCredential,
} from "firebase/auth";
try {
// Unenroll from TOTP MFA.
await multiFactor(currentUser).unenroll(mfaEnrollmentId);
} catch (error) {
if (error.code === 'auth/user-token-expired') {
// If the user was signed out, re-authenticate them.
// For example, if they signed in with a password, prompt them to
// provide it again, then call `reauthenticateWithCredential()` as shown
// below.
const credential = EmailAuthProvider.credential(email, password);
await reauthenticateWithCredential(
currentUser,
credential
);
}
}
ขั้นตอนถัดไป
- จัดการผู้ใช้แบบหลายปัจจัย แบบเป็นโปรแกรมด้วย Admin SDK