คุณใช้การตรวจสอบสิทธิ์ Firebase เพื่อให้ผู้ใช้ลงชื่อเข้าใช้ได้โดยส่งอีเมลที่มีลิงก์ให้ผู้ใช้คลิกเพื่อลงชื่อเข้าใช้ ในกระบวนการนี้ ระบบจะยืนยันอีเมลของผู้ใช้ด้วย
การลงชื่อเข้าใช้ด้วยอีเมลมีสิทธิประโยชน์มากมาย ดังนี้
- การลงชื่อสมัครใช้และการลงชื่อเข้าใช้ที่ง่ายดาย
- ลดความเสี่ยงในการใช้รหัสผ่านซ้ำในแอปพลิเคชันต่างๆ ซึ่งอาจบั่นทอนความปลอดภัย แม้ว่าจะเป็นรหัสผ่านที่เลือกมาอย่างดีก็ตาม
- ความสามารถในการตรวจสอบสิทธิ์ผู้ใช้พร้อมทั้งยืนยันว่าผู้ใช้เป็นเจ้าของอีเมลที่ถูกต้อง
- ผู้ใช้เพียงแค่ต้องมีบัญชีอีเมลที่เข้าถึงได้เพื่อลงชื่อเข้าใช้ ไม่ต้องเป็นเจ้าของหมายเลขโทรศัพท์หรือบัญชีโซเชียลมีเดีย
- ผู้ใช้สามารถลงชื่อเข้าใช้ได้อย่างปลอดภัยโดยไม่ต้องระบุ (หรือจดจำ) รหัสผ่าน ซึ่งอาจเป็นเรื่องยุ่งยากในอุปกรณ์เคลื่อนที่
- ผู้ใช้เดิมที่ลงชื่อเข้าใช้ด้วยตัวระบุอีเมล (รหัสผ่าน หรือแบบรวม) ก่อนหน้านี้สามารถอัปเกรดให้ลงชื่อเข้าใช้ด้วยอีเมลเพียงอย่างเดียวได้ เช่น ผู้ใช้ที่ลืมรหัสผ่านจะยังลงชื่อเข้าใช้ได้โดยไม่ต้อง รีเซ็ตรหัสผ่าน
ก่อนเริ่มต้น
หากยังไม่ได้ทำ ให้คัดลอกข้อมูลโค้ดการเริ่มต้นจากFirebaseคอนโซลไปยังโปรเจ็กต์ตามที่อธิบายไว้ในเพิ่ม Firebase ลงในโปรเจ็กต์ JavaScript
เปิดใช้การลงชื่อเข้าใช้ด้วยลิงก์อีเมลสำหรับโปรเจ็กต์ Firebase
หากต้องการให้ผู้ใช้ลงชื่อเข้าใช้ด้วยลิงก์อีเมล คุณต้องเปิดใช้ผู้ให้บริการอีเมลและ วิธีการลงชื่อเข้าใช้ด้วยลิงก์อีเมลสำหรับโปรเจ็กต์ Firebase ก่อน โดยทำดังนี้
ในคอนโซล Firebase ให้ไปที่ความปลอดภัย > การตรวจสอบสิทธิ์
ในแท็บวิธีการลงชื่อเข้าใช้ ให้เปิดใช้วิธีการลงชื่อเข้าใช้ด้วยอีเมล/รหัสผ่าน โปรดทราบว่าต้องเปิดใช้การลงชื่อเข้าใช้ด้วยอีเมล/รหัสผ่านก่อนจึงจะใช้การลงชื่อเข้าใช้ด้วยลิงก์ในอีเมลได้
ในส่วนเดียวกัน ให้เปิดใช้ผู้ให้บริการลงชื่อเข้าใช้ลิงก์อีเมล (การลงชื่อเข้าใช้แบบไม่มีรหัสผ่าน)
คลิกบันทึก
ส่งลิงก์การตรวจสอบสิทธิ์ไปยังอีเมลของผู้ใช้
หากต้องการเริ่มขั้นตอนการตรวจสอบสิทธิ์ ให้แสดงอินเทอร์เฟซที่
แจ้งให้ผู้ใช้ระบุอีเมล แล้วเรียกใช้
sendSignInLinkToEmail เพื่อขอให้ Firebase ส่งลิงก์การตรวจสอบสิทธิ์ไปยัง
อีเมลของผู้ใช้
สร้างออบเจ็กต์
ActionCodeSettingsซึ่งจะให้คำสั่งแก่ Firebase เกี่ยวกับวิธีสร้างลิงก์อีเมล ตั้งค่าช่องต่อไปนี้url: Deep Link ที่จะฝังและสถานะเพิ่มเติมที่จะส่งต่อ หากยังไม่ได้เพิ่ม ให้เพิ่มโดเมนลงในรายการโดเมนที่ได้รับอนุญาตโดยทำดังนี้ในFirebaseคอนโซล ให้ไปที่ ความปลอดภัย > การตรวจสอบสิทธิ์ > แท็บการตั้งค่า
ในส่วนโดเมนที่ได้รับอนุญาต ให้คลิกเพิ่มโดเมน แล้วเพิ่มโดเมน
androidและios: ช่วย Firebase Authentication ในการพิจารณาว่าจะสร้างลิงก์สำหรับเว็บเท่านั้นหรือลิงก์สำหรับมือถือซึ่งเปิดในอุปกรณ์ Android หรือ ApplehandleCodeInApp: ตั้งค่าเป็น "จริง" การดำเนินการลงชื่อเข้าใช้ต้องดำเนินการในแอปเสมอ ซึ่งแตกต่างจากการดำเนินการทางอีเมลอื่นๆ นอกแบนด์ (การรีเซ็ตรหัสผ่านและการยืนยันอีเมล) เนื่องจากในตอนท้ายของโฟลว์ ระบบคาดหวังให้ผู้ใช้ลงชื่อเข้าใช้และเก็บสถานะการให้สิทธิ์ไว้ภายใน แอปlinkDomain: เมื่อกำหนดโดเมนลิงก์ Hostingที่กำหนดเองสำหรับโปรเจ็กต์ ให้ระบุโดเมนที่จะใช้เมื่อแอปบนอุปกรณ์เคลื่อนที่ที่ระบุเปิดลิงก์ มิฉะนั้น ระบบจะเลือกโดเมนเริ่มต้นโดยอัตโนมัติ (เช่น )PROJECT_ID.firebaseapp.comdynamicLinkDomain: เลิกใช้งานแล้ว ไม่ต้องระบุพารามิเตอร์นี้Web
const actionCodeSettings = { // URL you want to redirect back to. The domain (www.example.com) for this // URL must be in the authorized domains list in the Firebase Console. url: 'https://www.example.com/finishSignUp?cartId=1234', // This must be true. handleCodeInApp: true, iOS: { bundleId: 'com.example.ios' }, android: { packageName: 'com.example.android', installApp: true, minimumVersion: '12' }, // The domain must be configured in Firebase Hosting and owned by the project. linkDomain: 'custom-domain.com' };
Web
var actionCodeSettings = { // URL you want to redirect back to. The domain (www.example.com) for this // URL must be in the authorized domains list in the Firebase Console. url: 'https://www.example.com/finishSignUp?cartId=1234', // This must be true. handleCodeInApp: true, iOS: { bundleId: 'com.example.ios' }, android: { packageName: 'com.example.android', installApp: true, minimumVersion: '12' }, dynamicLinkDomain: 'example.page.link' };
ดูข้อมูลเพิ่มเติมเกี่ยวกับ
ActionCodeSettingsได้ที่ส่วน การส่งสถานะในการดำเนินการทางอีเมลขออีเมลจากผู้ใช้
ส่งลิงก์การตรวจสอบสิทธิ์ไปยังอีเมลของผู้ใช้ และบันทึกอีเมลของผู้ใช้ ในกรณีที่ผู้ใช้ลงชื่อเข้าใช้อีเมลในอุปกรณ์เดียวกัน
Web
import { getAuth, sendSignInLinkToEmail } from "firebase/auth"; const auth = getAuth(); sendSignInLinkToEmail(auth, email, actionCodeSettings) .then(() => { // The link was successfully sent. Inform the user. // Save the email locally so you don't need to ask the user for it again // if they open the link on the same device. window.localStorage.setItem('emailForSignIn', email); // ... }) .catch((error) => { const errorCode = error.code; const errorMessage = error.message; // ... });
Web
firebase.auth().sendSignInLinkToEmail(email, actionCodeSettings) .then(() => { // The link was successfully sent. Inform the user. // Save the email locally so you don't need to ask the user for it again // if they open the link on the same device. window.localStorage.setItem('emailForSignIn', email); // ... }) .catch((error) => { var errorCode = error.code; var errorMessage = error.message; // ... });
ลงชื่อเข้าใช้ให้เสร็จด้วยลิงก์ในอีเมล
ข้อกังวลด้านความปลอดภัย
Firebase Auth กำหนดให้ต้องระบุอีเมลของผู้ใช้เมื่อทำขั้นตอนการลงชื่อเข้าใช้ให้เสร็จสมบูรณ์ เพื่อป้องกันไม่ให้มีการใช้ลิงก์การลงชื่อเข้าใช้เพื่อลงชื่อเข้าใช้ในฐานะผู้ใช้ที่ไม่ต้องการหรือในอุปกรณ์ที่ไม่ต้องการ อีเมลนี้ต้องตรงกับอีเมลที่ระบบส่งลิงก์ลงชื่อเข้าใช้ไปให้ในตอนแรกเพื่อให้ลงชื่อเข้าใช้ได้
คุณสามารถเพิ่มประสิทธิภาพขั้นตอนการทำงานนี้สำหรับผู้ใช้ที่เปิดลิงก์การลงชื่อเข้าใช้ในอุปกรณ์เดียวกันกับที่ขอลิงก์ได้โดยการจัดเก็บอีเมลของผู้ใช้ไว้ในเครื่อง เช่น ใช้ localStorage หรือคุกกี้ เมื่อคุณส่งอีเมลลงชื่อเข้าใช้ จากนั้น ใช้ที่อยู่นี้เพื่อทําขั้นตอนให้เสร็จสมบูรณ์ อย่าส่งอีเมลของผู้ใช้ในพารามิเตอร์ URL เปลี่ยนเส้นทางและนำกลับมาใช้ใหม่ เนื่องจากอาจทำให้มีการแทรกเซสชัน
หลังจากลงชื่อเข้าใช้เสร็จสมบูรณ์แล้ว ระบบจะนำกลไกการลงชื่อเข้าใช้ก่อนหน้านี้ที่ยังไม่ได้ยืนยัน ออกจากผู้ใช้ และจะทำให้เซสชันที่มีอยู่เป็นโมฆะ ตัวอย่างเช่น หากก่อนหน้านี้มีผู้สร้างบัญชีที่ไม่ได้รับการยืนยันโดยใช้อีเมลและรหัสผ่านเดียวกัน ระบบจะนำรหัสผ่านของผู้ใช้ออกเพื่อป้องกันไม่ให้ผู้แอบอ้างที่อ้างสิทธิ์ความเป็นเจ้าของและสร้างบัญชีที่ไม่ได้รับการยืนยันนั้นลงชื่อเข้าใช้อีกครั้งด้วยอีเมลและรหัสผ่านที่ไม่ได้รับการยืนยัน
นอกจากนี้ โปรดตรวจสอบว่าคุณใช้ URL HTTPS ในเวอร์ชันที่ใช้งานจริงเพื่อหลีกเลี่ยงไม่ให้เซิร์ฟเวอร์ตัวกลางอาจดักจับลิงก์ของคุณ
การลงชื่อเข้าใช้ในหน้าเว็บให้เสร็จสมบูรณ์
รูปแบบของ Deep Link ของลิงก์อีเมลจะเหมือนกับ
รูปแบบที่ใช้สำหรับการดำเนินการทางอีเมลนอกแบนด์
(การยืนยันอีเมล การรีเซ็ตรหัสผ่าน และการเพิกถอนการเปลี่ยนแปลงอีเมล)
Firebase Auth ช่วยให้การตรวจสอบนี้ง่ายขึ้นโดยการจัดเตรียม isSignInWithEmailLink API
เพื่อตรวจสอบว่าลิงก์เป็นลิงก์การลงชื่อเข้าใช้ด้วยอีเมลหรือไม่
หากต้องการลงชื่อเข้าใช้ในหน้า Landing Page ให้เสร็จสมบูรณ์ โปรดโทรหา signInWithEmailLink พร้อมระบุอีเมลของผู้ใช้และลิงก์อีเมลจริงที่มีรหัสแบบใช้ครั้งเดียว
Web
import { getAuth, isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth"; // Confirm the link is a sign-in with email link. const auth = getAuth(); if (isSignInWithEmailLink(auth, window.location.href)) { // Additional state parameters can also be passed via URL. // This can be used to continue the user's intended action before triggering // the sign-in operation. // Get the email if available. This should be available if the user completes // the flow on the same device where they started it. let email = window.localStorage.getItem('emailForSignIn'); if (!email) { // User opened the link on a different device. To prevent session fixation // attacks, ask the user to provide the associated email again. For example: email = window.prompt('Please provide your email for confirmation'); } // The client SDK will parse the code from the link for you. signInWithEmailLink(auth, email, window.location.href) .then((result) => { // Clear email from storage. window.localStorage.removeItem('emailForSignIn'); // You can access the new user by importing getAdditionalUserInfo // and calling it with result: // getAdditionalUserInfo(result) // You can access the user's profile via: // getAdditionalUserInfo(result)?.profile // You can check if the user is new or existing: // getAdditionalUserInfo(result)?.isNewUser }) .catch((error) => { // Some error occurred, you can inspect the code: error.code // Common errors could be invalid email and invalid or expired OTPs. }); }
Web
// Confirm the link is a sign-in with email link. if (firebase.auth().isSignInWithEmailLink(window.location.href)) { // Additional state parameters can also be passed via URL. // This can be used to continue the user's intended action before triggering // the sign-in operation. // Get the email if available. This should be available if the user completes // the flow on the same device where they started it. var email = window.localStorage.getItem('emailForSignIn'); if (!email) { // User opened the link on a different device. To prevent session fixation // attacks, ask the user to provide the associated email again. For example: email = window.prompt('Please provide your email for confirmation'); } // The client SDK will parse the code from the link for you. firebase.auth().signInWithEmailLink(email, window.location.href) .then((result) => { // Clear email from storage. window.localStorage.removeItem('emailForSignIn'); // You can access the new user via result.user // Additional user info profile not available via: // result.additionalUserInfo.profile == null // You can check if the user is new or existing: // result.additionalUserInfo.isNewUser }) .catch((error) => { // Some error occurred, you can inspect the code: error.code // Common errors could be invalid email and invalid or expired OTPs. }); }
การลงชื่อเข้าใช้ในแอปบนอุปกรณ์เคลื่อนที่ให้เสร็จสมบูรณ์
Firebase Authentication ใช้ Firebase Hosting เพื่อส่งลิงก์อีเมลไปยังอุปกรณ์เคลื่อนที่ สำหรับการลงชื่อเข้าใช้ผ่านแอปพลิเคชันบนอุปกรณ์เคลื่อนที่ คุณต้องกำหนดค่าแอปพลิเคชันเพื่อตรวจหาลิงก์แอปพลิเคชันขาเข้า แยกวิเคราะห์ Deep Link พื้นฐาน แล้วจึงลงชื่อเข้าใช้ให้เสร็จสมบูรณ์เหมือนกับที่ทำผ่านขั้นตอนบนเว็บ
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดการการลงชื่อเข้าใช้ด้วยลิงก์อีเมลในแอปพลิเคชัน Android ได้ที่คู่มือ Android
ดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีจัดการการลงชื่อเข้าใช้ด้วยลิงก์อีเมลในแอปพลิเคชันของ Apple ได้ที่คู่มือแพลตฟอร์มของ Apple
การลิงก์/การตรวจสอบสิทธิ์ซ้ำด้วยลิงก์ในอีเมล
นอกจากนี้ คุณยังลิงก์วิธีการตรวจสอบสิทธิ์นี้กับผู้ใช้ที่มีอยู่ได้ด้วย ตัวอย่างเช่น ผู้ใช้ที่เคยยืนยันตัวตนกับผู้ให้บริการรายอื่น เช่น หมายเลขโทรศัพท์ สามารถเพิ่มวิธีการลงชื่อเข้าใช้นี้ลงในบัญชีที่มีอยู่ได้
ความแตกต่างจะอยู่ในครึ่งหลังของการดำเนินการ
Web
import { getAuth, linkWithCredential, EmailAuthProvider } from "firebase/auth"; // Construct the email link credential from the current URL. const credential = EmailAuthProvider.credentialWithLink( email, window.location.href); // Link the credential to the current user. const auth = getAuth(); linkWithCredential(auth.currentUser, credential) .then((usercred) => { // The provider is now successfully linked. // The phone user can now sign in with their phone number or email. }) .catch((error) => { // Some error occurred. });
Web
// Construct the email link credential from the current URL. var credential = firebase.auth.EmailAuthProvider.credentialWithLink( email, window.location.href); // Link the credential to the current user. firebase.auth().currentUser.linkWithCredential(credential) .then((usercred) => { // The provider is now successfully linked. // The phone user can now sign in with their phone number or email. }) .catch((error) => { // Some error occurred. });
นอกจากนี้ ยังใช้เพื่อตรวจสอบสิทธิ์ผู้ใช้ลิงก์อีเมลอีกครั้งก่อนที่จะเรียกใช้ การดำเนินการที่ละเอียดอ่อนได้ด้วย
Web
import { getAuth, reauthenticateWithCredential, EmailAuthProvider } from "firebase/auth"; // Construct the email link credential from the current URL. const credential = EmailAuthProvider.credentialWithLink( email, window.location.href); // Re-authenticate the user with this credential. const auth = getAuth(); reauthenticateWithCredential(auth.currentUser, credential) .then((usercred) => { // The user is now successfully re-authenticated and can execute sensitive // operations. }) .catch((error) => { // Some error occurred. });
Web
// Construct the email link credential from the current URL. var credential = firebase.auth.EmailAuthProvider.credentialWithLink( email, window.location.href); // Re-authenticate the user with this credential. firebase.auth().currentUser.reauthenticateWithCredential(credential) .then((usercred) => { // The user is now successfully re-authenticated and can execute sensitive // operations. }) .catch((error) => { // Some error occurred. });
อย่างไรก็ตาม เนื่องจากโฟลว์อาจสิ้นสุดในอุปกรณ์อื่นที่ผู้ใช้เดิมไม่ได้เข้าสู่ระบบ โฟลว์นี้จึงอาจไม่เสร็จสมบูรณ์ ในกรณีดังกล่าว ระบบอาจแสดงข้อผิดพลาดต่อผู้ใช้เพื่อบังคับให้ผู้ใช้เปิดลิงก์ในอุปกรณ์เดียวกัน คุณส่ง สถานะบางอย่างในลิงก์เพื่อระบุข้อมูลเกี่ยวกับประเภทการดำเนินการ และรหัสผู้ใช้ได้
เลิกใช้งาน: การแยกความแตกต่างระหว่างอีเมลและรหัสผ่านกับลิงก์อีเมล
หากสร้างโปรเจ็กต์ตั้งแต่วันที่ 15 กันยายน 2023 เป็นต้นไป ระบบจะเปิดใช้การป้องกันการแจกแจงอีเมล
โดยค่าเริ่มต้น ฟีเจอร์นี้ช่วยปรับปรุงความปลอดภัยของบัญชีผู้ใช้ในโปรเจ็กต์ แต่จะปิดใช้fetchSignInMethodsForEmail()
วิธี ซึ่งก่อนหน้านี้เราแนะนำให้ใช้เพื่อติดตั้งใช้งานโฟลว์ที่ใช้ตัวระบุเป็นอันดับแรก
แม้ว่าคุณจะปิดใช้การป้องกันการแจงนับอีเมลสำหรับโปรเจ็กต์ได้ แต่เราไม่แนะนำให้ทำเช่นนั้น
ดูรายละเอียดเพิ่มเติมได้ในเอกสารประกอบเกี่ยวกับการป้องกันการแจงนับอีเมล
เทมเพลตอีเมลเริ่มต้นสำหรับการลงชื่อเข้าใช้ด้วยลิงก์
เทมเพลตอีเมลเริ่มต้นมีการประทับเวลาในเรื่องและเนื้อหาของอีเมล เพื่อให้ระบบไม่ยุบอีเมลที่ตามมาเป็นชุดข้อความเดียวและซ่อนลิงก์
เทมเพลตนี้ใช้ได้กับภาษาต่อไปนี้
| รหัส | ภาษา |
|---|---|
| ar | อาหรับ |
| zh-CN | จีน (ตัวย่อ) |
| zh-TW | จีน (ดั้งเดิม) |
| nl | ดัตช์ |
| en | อังกฤษ |
| en-GB | อังกฤษ (สหราชอาณาจักร) |
| fr | ฝรั่งเศส |
| de | เยอรมัน |
| id | อินโดนีเซีย |
| it | อิตาลี |
| ja | ญี่ปุ่น |
| ko | เกาหลี |
| pl | โปแลนด์ |
| pt-BR | โปรตุเกส (บราซิล) |
| pt-PT | โปรตุเกส (โปรตุเกส) |
| ru | รัสเซีย |
| es | สเปน |
| es-419 | สเปน (ลาตินอเมริกา) |
| th | ไทย |
ขั้นตอนถัดไป
หลังจากที่ผู้ใช้ลงชื่อเข้าใช้เป็นครั้งแรก ระบบจะสร้างบัญชีผู้ใช้ใหม่และ ลิงก์กับข้อมูลเข้าสู่ระบบ ซึ่งได้แก่ ชื่อผู้ใช้และรหัสผ่าน หมายเลขโทรศัพท์ หรือข้อมูลผู้ให้บริการตรวจสอบสิทธิ์ที่ผู้ใช้ลงชื่อเข้าใช้ ระบบจะจัดเก็บบัญชีใหม่นี้เป็นส่วนหนึ่งของโปรเจ็กต์ Firebase และสามารถใช้เพื่อระบุผู้ใช้ในทุกแอปในโปรเจ็กต์ได้ ไม่ว่าผู้ใช้จะลงชื่อเข้าใช้ด้วยวิธีใดก็ตาม
-
ในแอป วิธีที่แนะนำในการทราบสถานะการให้สิทธิ์ของผู้ใช้คือการ ตั้งค่า Observer ในออบเจ็กต์
Authจากนั้นคุณจะดูข้อมูลโปรไฟล์พื้นฐานของผู้ใช้ได้จากออบเจ็กต์Userดูจัดการผู้ใช้ ใน Firebase Realtime Database และ Cloud Storage กฎความปลอดภัย คุณสามารถ รับรหัสผู้ใช้ที่ไม่ซ้ำของผู้ใช้ที่ลงชื่อเข้าใช้จากตัวแปร
authและใช้รหัสดังกล่าวเพื่อควบคุมข้อมูลที่ผู้ใช้เข้าถึงได้
คุณอนุญาตให้ผู้ใช้ลงชื่อเข้าใช้แอปโดยใช้ผู้ให้บริการการตรวจสอบสิทธิ์หลายรายได้โดยลิงก์ข้อมูลเข้าสู่ระบบของผู้ให้บริการการตรวจสอบสิทธิ์กับบัญชีผู้ใช้ที่มีอยู่
หากต้องการให้ออกจากระบบ ให้โทรหา
signOut
Web
import { getAuth, signOut } from "firebase/auth"; const auth = getAuth(); signOut(auth).then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });
Web
firebase.auth().signOut().then(() => { // Sign-out successful. }).catch((error) => { // An error happened. });