Giới thiệu
Hướng dẫn này là phần bổ sung cho Cách thiết lập xác thực Firebase bằng ứng dụng web React . Trong phần giới thiệu của hướng dẫn đó, tôi đã lưu ý rằng Firebase cung cấp các chương trình xác thực khác ngoài xác thực Email/Mật khẩu cơ bản. Một trong những lựa chọn thay thế đó là Xác thực không cần mật khẩu .
Xác thực không cần mật khẩu là một lựa chọn hấp dẫn khi xây dựng ứng dụng. Nó đơn giản hóa trải nghiệm người dùng vì người dùng của bạn không cần phải nhớ (các) mật khẩu của họ và do đó không bao giờ phải lo lắng về việc mất chúng. Nó cũng tạo điều kiện thuận lợi cho trải nghiệm phát triển vì không cần thiết kế bất kỳ logic quản lý hoặc thu thập mật khẩu nào.
Trong hướng dẫn này, bạn sẽ xây dựng quy trình làm việc Đăng nhập/Xác nhận/Hồ sơ/Đăng xuất đơn giản để triển khai xác thực không cần mật khẩu của Firebase.
Trước khi bắt đầu
Google đặt ra nhiều giới hạn Xác thực Firebase khác nhau. Nếu bạn đang sử dụng gói Spark miễn phí, hãy lưu ý rằng bạn sẽ bị giới hạn 5 email liên kết đăng nhập mỗi ngày. Mặc dù gói Spark có thể đủ cho mục đích thử nghiệm nhưng bạn sẽ cần nâng cấp lên gói Blaze trả tiền khi sử dụng để vượt quá giới hạn này.
Điều kiện tiên quyết
Trong suốt hướng dẫn này, tôi sẽ tham khảo Cách thiết lập xác thực Firebase với hướng dẫn Ứng dụng web React làm hướng dẫn tiên quyết và dự án liên quan làm dự án tiên quyết .
Để hoàn thành hướng dẫn này, bạn sẽ cần phải có:
- Đã hoàn thành hướng dẫn điều kiện tiên quyết, bao gồm tất cả các điều kiện tiên quyết của nó.
Bước 1 - Kích hoạt xác thực không cần mật khẩu với dự án Firebase của bạn
Trong hướng dẫn tiên quyết, bạn đã tạo dự án Firebase mới để xác thực email/mật khẩu cơ bản. Bây giờ, bạn sẽ kích hoạt chính dự án đó để xác thực không cần mật khẩu. Đăng nhập vào tài khoản Firebase của bạn và nhấp vào Go to Console .
Nhấp vào dự án xác thực của bạn được liệt kê trên trang tổng quan dự án Firebase. Hướng dẫn này sử dụng tên dự án
my-auth-test
.Nhấp vào xác thực trong menu bảng điều khiển bên trái.
Nhấp vào tab Phương thức đăng nhập trong cửa sổ chính.
Từ công việc của bạn trong hướng dẫn điều kiện tiên quyết, bảng Nhà cung cấp đăng nhập phải hiển thị Email/Mật khẩu trong cột Nhà cung cấp với trạng thái Đã bật . Nhấp vào biểu tượng bút chì để mở bảng cấu hình cho nhà cung cấp Email/Mật khẩu .
Nhấp vào nút chuyển đổi để bật liên kết Email (đăng nhập không cần mật khẩu) .
Nhấp vào Lưu .
Dự án Firebase của bạn hiện đã được định cấu hình để hỗ trợ xác thực không cần mật khẩu.
Bước 2 - Tạo dự án React mới và cài đặt gói
Bước 2a - Tạo một dự án React mới
Tạo một dự án React mới bằng tên ứng dụng bạn muốn. Hướng dẫn này sử dụng passwordless-auth
.
npx create-react-app passwordless-auth
Bước 2b - Cài đặt gói
Hướng dẫn này yêu cầu cài đặt 3 gói Node.js:
- Firebase : SDK Firebase.
- React Router DOM : Để định tuyến.
- Bootstrap : Để tạo kiểu.
Cài đặt từng gói trong ba gói trên thông qua npm
:
npm install firebase
npm install react-router-dom
npm install bootstrap
Bước 3 - Sao chép firebase.js
từ Dự án tiên quyết
Trong dự án tiên quyết, bạn đã tạo tệp firebase.js
sử dụng dữ liệu cấu hình dự án Firebase để tạo phiên bản của dịch vụ Xác thực Firebase. Tệp firebase.js
của bạn phải có cấu trúc sau với các giá trị cấu hình dự án Firebase của bạn :
import { initializeApp } from "firebase/app"; import { getAuth } from "firebase/auth"; const firebaseConfig = { apiKey: "AIzaSyDiUlY68W9Li_0EIkmdGdzD7nvqCT9kHnY", authDomain: "my-auth-test-fbd48.firebaseapp.com", projectId: "my-auth-test-fbd48", storageBucket: "my-auth-test-fbd48.appspot.com", messagingSenderId: "1078604952662", appId: "1:1078604952662:web:5d0b908439cfb5684ab7f7" } const app = initializeApp(firebaseConfig); const auth = getAuth(app); export { auth }
Sao chép firebase.js
vào thư mục dự án React mới của bạn.
Nếu bạn cần xem lại cấu hình dự án Firebase của mình, hãy nhấp vào biểu tượng bánh răng bên cạnh Tổng quan về dự án trong menu bảng điều khiển bên trái. Tab Chung đã được chọn. Cuộn xuống phần Ứng dụng của bạn chứa bảng Ứng dụng web . Tùy chọn npm trong bảng ứng dụng Web đã được chọn. Giá trị cấu hình dự án của bạn sẽ được liệt kê trong khối mã được hiển thị.
Bước 4 - Xây dựng ứng dụng React
Bước 4a - Tổng quan về các thành phần ứng dụng React
Ứng dụng React sẽ bao gồm 5 thành phần: App
, Layout
, Login
, Confirm
và Profile
.
App
- Thành phần
App
xác định cấu trúc ứng dụng tổng thể, bao gồm cả định tuyến.
Layout
- Thành phần
Layout
chỉ định đánh dấu ứng dụng luôn nhất quán trên tất cả các tuyến.
Login
- Điểm vào của người dùng vào ứng dụng là biểu mẫu đăng nhập.
- Khi người dùng cố gắng đăng nhập qua địa chỉ email của mình, một email có liên kết đăng nhập sẽ được gửi đến địa chỉ email của họ.
Confirm
- Người dùng được chuyển đến trang
Confirm
khi họ nhấp vào liên kết đăng nhập. - Trang yêu cầu người dùng xác nhận địa chỉ email được sử dụng khi họ đăng nhập.
Profile
- Người dùng được chuyển đến trang
Profile
sau khi xác nhận địa chỉ email của họ. - Người dùng có thể nhấp vào nút đăng xuất trên trang
Profile
để đăng xuất khỏi tài khoản của mình.
Thư mục src
cuối cùng sẽ chứa các file sau:
src |__ index.js |__ firebase.js // Copied from prerequisite project in Step 3. |__ App.js |__ Layout.jsx |__ Login.jsx |__ Confirm.jsx |__ Profile.jsx
Bước 4b - Dọn dẹp mẫu dự án React và sao chép tệp từ dự án tiên quyết
- Bạn có thể xóa các tệp tương tự khỏi mẫu dự án React như được mô tả ở Bước 5b.1 của hướng dẫn tiên quyết. Xóa các tệp sau khỏi dự án React của bạn:
-
reportWebVitals.js
-
setupTests.js
-
logo.svg
-
index.css
-
App.css
-
App.test.js
Sao chép
index.js
từ dự án tiên quyết vào thư mục dự án mới của bạn. Hướng dẫn này sử dụng cùng một tập tin. Nếu bạn cần xây dựng lạiindex.js
, hãy xem Bước 5b.2 của hướng dẫn điều kiện tiên quyết hoặc sao chép khối mã bên dưới.Sao chép
Layout.jsx
từ dự án tiên quyết vào thư mục dự án mới của bạn. Hướng dẫn này sử dụng cùng một tập tin. Nếu bạn cần xây dựng lạiLayout.jsx
, hãy xem Bước 5d của hướng dẫn điều kiện tiên quyết hoặc sao chép khối mã bên dưới. Theo tùy chọn, bạn có thể cập nhật văn bản dự án trong thẻ<p>
củaLayout.jsx
đểReact With Firebase Passwordless Authentication
hoặc bất kỳ tiêu đề nào bạn thích.
Các tệp index.js
và Layout.jsx
của bạn phải như sau:
// index.js import React from 'react'; import ReactDOM from 'react-dom/client'; import App from './App'; import "bootstrap/dist/css/bootstrap.min.css"; const root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <App /> </React.StrictMode> );
// Layout.jsx import { Outlet } from "react-router-dom"; const Layout = () => { return( <div className = "container-fluid"> <div className = "row justify-content-center mt-3"> <div className = "col-md-4 text-center"> <p className = "lead">React With Firebase Passwordless Authentication</p> </div> <Outlet /> </div> </div> ) } export default Layout
Bước 4c - Xây dựng App.js
Tệp App.js
phần lớn giống như trong dự án tiên quyết, chỉ thay đổi hai dòng. Để tạo điều kiện thuận lợi cho việc xây dựng tệp, hãy sao chép App.js
từ dự án tiên quyết vào thư mục dự án mới của bạn.
Xóa dòng
import
sau khỏi tệp và thay thế nó như hiển thị bên dưới:
// Delete this line: import Signup from "./Signup";
// Replace it with: import Confirm from "./Confirm";
Xóa
<Route>
sau khỏi tệp và thay thế nó như hiển thị bên dưới:
// Delete this line: <Route path = "/signup" element = { <Signup></Signup> } ></Route>
// Replace it with: <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route>
Lưu
App.js
.
Tệp hoàn chỉnh bây giờ sẽ như sau:
import Layout from "./Layout"; import Login from "./Login"; import Confirm from "./Confirm"; import Profile from "./Profile"; import { BrowserRouter, Routes, Route } from "react-router-dom"; const App = () => { return ( <BrowserRouter> <Routes> <Route path = "/" element = { <Layout></Layout> }> <Route index element = { <Login></Login> }></Route> <Route path = "/confirm" element = { <Confirm></Confirm> } ></Route> <Route path = "/profile" element = { <Profile></Profile> } ></Route> </Route> </Routes> </BrowserRouter> ) } export default App
Lưu ý rằng thành phần Login
một lần nữa lại là tuyến đường chính của ứng dụng giống như với dự án tiên quyết.
Bước 4d - Xây dựng Login.jsx
Trong trường hợp xác thực không cần mật khẩu, rõ ràng bạn không cần bao gồm trường mật khẩu và cũng không cần quản lý trạng thái để nhập mật khẩu. Vì vậy, biểu mẫu đăng nhập chỉ cần nắm bắt địa chỉ email của người dùng.
Tạo một tệp
Login.jsx
mới trong thư mụcsrc
.Thêm mã sau đây:
import { useState } from "react"; import { auth } from "./firebase"; import { sendSignInLinkToEmail } from "firebase/auth"; const Login = () => { const [email, setEmail] = useState(""); const [notice, setNotice] = useState(""); const actionCodeSettings = { url: "http://localhost:3000/confirm", handleCodeInApp: true } const callSendSignInLinkToEmail = (e) => { e.preventDefault(); sendSignInLinkToEmail(auth, email, actionCodeSettings) .then(() => { setNotice("An email was sent to your email address. Click the link in the email to login."); }) .catch((error) => { setNotice("An error occurred when sending a login link to your email address: ", error.name); }) } return( <div className = "container"> <div className = "row justify-content-center"> <form className = "col-md-4 mt-3 pt-3 pb-3"> { "" !== notice && <div className = "alert alert-warning" role = "alert"> { notice } </div> } <div className = "form-floating mb-3"> <input type = "email" className = "form-control" id = "exampleInputEmail" placeholder = "[email protected]" value = { email } onChange = { (e) => setEmail(e.target.value) }></input> <label htmlFor = "exampleInputEmail" className = "form-label">Email address</label> </div> <div className = "d-grid"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => callSendSignInLinkToEmail(e)}>Submit</button> </div> </form> </div> </div> ) }
- Lưu
Login.jsx
.
Khi lấy được địa chỉ email của người dùng, biểu mẫu Login.jsx
sẽ gửi email có liên kết đăng nhập đến địa chỉ của người dùng đó thông qua phương thức sendSignInLinkToEmail
của Firebase. Nếu thành công, người dùng sẽ được thông báo rằng email đã được gửi. Lưu ý rằng đối tượng actionCodeSettings
được truyền dưới dạng tham số cho phương thức sendSignInLinkToEmail
và bao gồm URL mà người dùng sẽ được chuyển đến khi họ nhấp vào liên kết đăng nhập được gửi qua email. Trong trường hợp này, URL sẽ ánh xạ tới tuyến /confirm
được chỉ định trong App.js
.
Bước 4e - Xây dựng Confirm.jsx
Phương thức signInWithEmailLink
của Firebase được sử dụng để đăng nhập người dùng đã nhấp vào liên kết đăng nhập. Như bạn sẽ thấy ngay sau đây, phương thức này lấy một tham số email
và giá trị của email
phải khớp với địa chỉ email mà người dùng đã sử dụng khi đăng nhập qua biểu mẫu đăng nhập. Confirm.jsx
cung cấp cho người dùng một biểu mẫu để xác nhận địa chỉ email của họ và sau đó thử đăng nhập vào người dùng.
Tạo tệp
Confirm.jsx
mới trong thư mụcsrc
.Thêm mã sau đây:
import { useState } from "react"; import { auth } from "./firebase"; import { isSignInWithEmailLink, signInWithEmailLink } from "firebase/auth"; import { useNavigate } from "react-router-dom"; const Confirm = () => { const navigate = useNavigate(); const [email, setEmail] = useState(""); const [notice, setNotice] = useState(""); const callSignInWithEmailLink = (e) => { e.preventDefault(); if (isSignInWithEmailLink(auth, window.location.href)) { signInWithEmailLink(auth, email, window.location.href) .then(() => { navigate("/profile"); }) .catch((error) => { setNotice("An occurred during sign in: ", error.name); }) } } return( <div className = "container"> <div className = "row justify-content-center"> <form className = "col-md-4 mt-3 pt-3 pb-3"> { "" !== notice && <div className = "alert alert-warning" role = "alert"> { notice } </div> } <div className = "form-floating mb-3"> <input type = "email" className = "form-control" id = "exampleConfirmEmail" placeholder = "[email protected]" value = { email } onChange = { (e) => setEmail(e.target.value) }></input> <label htmlFor = "exampleConfirmEmail" className = "form-label">Please confirm your email address</label> </div> <div className = "d-grid"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => callSignInWithEmailLink(e)}>Confirm</button> </div> </form> </div> </div> ) } export default Confirm
- Lưu Xác
Confirm.jsx
.
Phương thức isSignInWithEmailLink
trước tiên sẽ kiểm tra xem liên kết đăng nhập mà người dùng đang sử dụng có hợp lệ hay không. Nếu đúng như vậy, phương thức signInWithEmailLink
sẽ được gọi để đăng nhập người dùng. Để nhắc lại, giá trị email
được truyền cho phương thức signInWithEmailLink
phải khớp với địa chỉ email mà người dùng đã sử dụng với biểu mẫu đăng nhập. Lưu ý rằng nếu người dùng là người dùng mới (tức là đây là lần đầu tiên họ đăng nhập), Firebase sẽ tự động tạo người dùng trong cửa hàng Xác thực Firebase. Đây là một ví dụ khác về trải nghiệm đơn giản hóa được cung cấp bởi xác thực không mật khẩu: việc tạo tài khoản cho người dùng mới được xử lý tự động.
Bước 4f - Xây dựng Profile.jsx
Thành phần cuối cùng mà bạn sẽ xây dựng là Profile.jsx
. Người dùng được chuyển đến thành phần này khi họ đăng nhập thành công qua Confirm.jsx
. Tuyến chào đón người dùng bằng địa chỉ email của họ và cung cấp nút để đăng xuất. Sau khi đăng xuất, người dùng được chuyển trở lại thành phần Login
.
Tạo một tệp
Profile.jsx
mới trong thư mụcsrc
.Thêm mã sau đây:
import { auth } from "./firebase"; import { signOut } from "firebase/auth"; import { useNavigate } from "react-router-dom"; const Profile = () => { const navigate = useNavigate(); const logoutUser = async (e) => { e.preventDefault(); await signOut(auth); navigate("/"); } return( <div className = "container"> <div className = "row justify-content-center"> <div className = "col-md-4 text-center"> <p>Welcome <em className = "text-decoration-underline">{ auth.currentUser.email }</em>. You are logged in!</p> <div className = "d-grid gap-2"> <button type = "submit" className = "btn btn-primary pt-3 pb-3" onClick = {(e) => logoutUser(e)}>Logout</button> </div> </div> </div> </div> ) } export default Profile
- Lưu
Profile.jsx
.
Bước 5 - Kiểm tra ứng dụng
Khởi động ứng dụng React:
npm start
- Điều hướng đến
locahost:3000
trong trình duyệt của bạn nếu trình duyệt của bạn không tự động khởi chạy. Bạn sẽ thấy biểu mẫuLogin
.
Nhập email bạn muốn sử dụng để đăng nhập và nhấp vào Gửi . Nếu gửi thành công, một thông báo sẽ hiển thị rằng một email có liên kết đăng nhập đã được gửi đến địa chỉ email của bạn.
- Đăng nhập vào tài khoản email của bạn và tìm email liên kết đăng nhập Firebase. Nó phải có dòng chủ đề tương tự như
Sign in to project-1078604952662
trong đó dãy số gồm 13 chữ số biểu thịmessagingSenderId
của dự án Firebase của bạn (xem Bước 3 của hướng dẫn này). Trong phần Tùy chọn bên dưới, tôi sẽ giải thích cách bạn có thể sửa đổi tên dự án Firebase của mình để hiển thị tên "thân thiện với người dùng" trong email liên kết đăng nhập. Bây giờ, hãy mở email liên kết đăng nhập và nhấp vào liên kết đăng nhập. Bạn sẽ được chuyển đến biểu mẫuConfirm
.
Nhập địa chỉ email bạn đã sử dụng khi đăng nhập vào biểu mẫu
Confirm
. Nhấp vào Xác nhận . Nếu xác nhận thành công, bạn sẽ được chuyển đến trangProfile
.
Nhấp vào nút Đăng xuất trên trang
Profile
để đăng xuất. Nếu đăng xuất thành công, bạn sẽ được chuyển trở lại biểu mẫuLogin
.
Các bước trên nắm bắt quy trình làm việc của ứng dụng.
Tùy chọn: Sửa đổi tên dự án của bạn
Bạn có thể thay đổi tên dự án của mình để các email liên kết đăng nhập do Firebase gửi hiển thị tên "thân thiện với người dùng" thay vì, chẳng hạn như project-1078604952662
. Đăng nhập vào tài khoản Firebase của bạn và nhấp vào Go to Console .
- Nhấp vào dự án xác thực của bạn được liệt kê trên trang tổng quan dự án Firebase.
- Nhấp vào biểu tượng bánh răng bên cạnh Tổng quan dự án trong menu bảng điều khiển bên trái. Tab Chung đã được chọn.
- Cuộn xuống tùy chọn Tên công khai trong phần Dự án của bạn .
- Nhấp vào biểu tượng bút chì và sửa đổi tên dự án của bạn theo ý muốn.
- Nhấp vào Lưu . Email liên kết đăng nhập của bạn bây giờ sẽ hiển thị tên dự án được cập nhật.
Kết luận và các bước tiếp theo
Xác thực không cần mật khẩu dường như là một lựa chọn ngày càng phổ biến của các nhà phát triển ứng dụng và điều đó cũng dễ hiểu. Ngoài lợi thế rõ ràng là loại bỏ nhu cầu quản lý mật khẩu, còn không cần xác minh email vì quá trình gửi liên kết đăng nhập tự nó là một quá trình xác minh.
Giống như dự án tiên quyết, việc triển khai ở đây là cơ bản. Bạn có thể xem xét các cải tiến đơn giản như:
Chặn/đưa vào danh sách đen các miền địa chỉ email cụ thể (tức là các miền email spam phổ biến).
Lưu trữ cục bộ địa chỉ email được người dùng nhập trên trang
Login
và kiểm tra sự tồn tại của địa chỉ email trên trangConfirm
. Với phương pháp này, nếu người dùng nhấp vào liên kết đăng nhập trên cùng một thiết bị mà họ đã truy cập trangLogin
, họ sẽ không cần nhập lại địa chỉ email của mình trên trangConfirm
vì địa chỉ đó sẽ được khôi phục từ bộ nhớ cục bộ. Điều này mang lại trải nghiệm người dùng mượt mà hơn nữa.
Bạn có thể tìm hiểu thêm về Xác thực không mật khẩu Firebase thông qua tài liệu chính thức .