Cách xử lý Quy trình công việc quên và đặt lại mật khẩu bằng React và Node.js
Hệ thống xác thực đóng một vai trò quan trọng trong việc cung cấp trải nghiệm người dùng liền mạch và an toàn. Quy trình xác thực thường bao gồm hai quy trình: đăng ký và đăng nhập.
Khi số lượng dịch vụ trực tuyến tăng lên, mọi người tạo tài khoản và mỗi tài khoản yêu cầu thông tin đăng nhập duy nhất. Tuy nhiên, điều này khiến bạn dễ quên hoặc nhầm lẫn thông tin đăng nhập. Để giải quyết vấn đề này, ứng dụng của bạn nên triển khai tính năng đặt lại mật khẩu cho phép người dùng đặt lại mật khẩu của họ một cách thuận tiện và an toàn.
Mục Lục
Thiết lập dự án React
Bạn có thể triển khai quy trình đặt lại mật khẩu theo nhiều cách khác nhau—không có một tiêu chuẩn chung nào mà mọi ứng dụng phải tuân theo. Thay vào đó, bạn nên điều chỉnh phương pháp bạn chọn để đáp ứng các nhu cầu cụ thể của ứng dụng của bạn.
Quy trình làm việc mà bạn sẽ tìm hiểu ở đây bao gồm các bước sau:
Để bắt đầu, hãy khởi động nhanh một dự án React. Tiếp theo, cài đặt Axios, thư viện yêu cầu HTTP JavaScript.
npm install axios
Tạo một thành phần đăng nhập
Trong thư mục src, tạo mới thành phần/Login.js tập tin và thêm mã sau đây. Bắt đầu bằng cách xác định quy trình đặt lại mật khẩu:
import axios from "axios";
import React, { useState } from "react";
import { useContext } from "react";
import { RecoveryContext } from "../App";
import "./global.component.css";export default function Login() {
const { setPage, setOTP, setEmail } = useContext(RecoveryContext);
const [userEmail, setUserEmail] = useState("");
function sendOtp() {
if (userEmail) {
axios.get(`http://localhost:5000/check_email?email=${userEmail}`).then((response) => {
if (response.status === 200) {
const OTP = Math.floor(Math.random() * 9000 + 1000);
console.log(OTP);
setOTP(OTP);
setEmail(userEmail);
axios.post("http://localhost:5000/send_email", {
OTP,
recipient_email: userEmail,
})
.then(() => setPage("otp"))
.catch(console.log);
} else {
alert("User with this email does not exist!");
console.log(response.data.message);
}}).catch(console.log);
} else {
alert("Please enter your email");
}}
Mã này tạo chức năng gửi Mật khẩu sử dụng một lần (OTP) đến địa chỉ email của người dùng. Trước tiên, nó xác minh người dùng bằng cách kiểm tra email của họ trong cơ sở dữ liệu trước khi tạo và gửi OTP. Cuối cùng, nó cập nhật giao diện người dùng với trang OTP.
Hoàn thành thành phần đăng nhập bằng cách thêm mã để hiển thị thành phần biểu mẫu JSX đăng nhập:
return (
<div>
<h2>Login</h2> <form>
<label /> Email:
<input type="email" value={userEmail} onChange={(e) => { setUserEmail(e.target.value) }} />
<label /> Password:
<input type="password" />
<button type="submit">login</button>
</form>
<a href="#" onClick={() => sendOtp()}>
Forgot Password
</a>
</div>
);
}
Tạo Thành phần xác minh OTP
Để đảm bảo tính hợp lệ của mã do người dùng nhập, bạn cần so sánh mã đó với mã được gửi đến email của họ.
Tạo một cái mới thành phần/OTPInput.js tập tin và thêm mã này:
import React, { useState, useContext, useEffect } from "react";
import { RecoveryContext } from "../App";
import axios from "axios";
import "./global.component.css";export default function OTPInput() {
const { email, otp, setPage } = useContext(RecoveryContext);
const [OTPinput, setOTPinput] = useState( "");
function verifyOTP() {
if (parseInt(OTPinput) === otp) {
setPage("reset");
} else {
alert("The code you have entered is not correct, try again re-send the link");
}
}
Mã này tạo một thành phần React nơi người dùng xác minh mã OTP của họ. Nó kiểm tra xem mã đã nhập có khớp với mã được lưu trữ trong đối tượng ngữ cảnh hay không. Nếu nó hợp lệ, nó sẽ hiển thị trang đặt lại mật khẩu. Ngược lại, nó hiển thị cảnh báo nhắc người dùng thử lại hoặc gửi lại OTP.
Bạn có thể kiểm tra mã trong kho lưu trữ này thực hiện chức năng gửi lại OTP và hẹn giờ hết hạn cho mã OTP.
Cuối cùng, kết xuất các phần tử JSX đầu vào.
return (
<div>
<h3>Email Verification</h3>
<p>We have sent a verification code to your email.</p>
<form>
<input type="text" value={OTPinput} onChange={(e) => { setOTPinput(e.target.value) }} />
<button onClick={() => verifyOTP()}>Verify Account</button>
<a onClick={() => resendOTP()} > Didn't receive code?
{disable ? `Resend OTP in ${timerCount}s` : " Resend OTP"}
</a>
</form>
</div>
);}
Tạo Thành phần Đặt lại Mật khẩu
Tạo một cái mới thành phần/Reset.js tập tin và thêm mã này:
import React, {useState, useContext} from "react";
import { RecoveryContext } from "../App";
import axios from "axios";
import "./global.component.css";export default function Reset() {
const [password, setPassword] = useState("");
const { setPage, email } = useContext(RecoveryContext);
function changePassword() {
if (password) {
try {
axios.put("http://localhost:5000/update-password", {
email:email,
newPassword: password,
}).then(() => setPage("login"));
return alert("Password changed successfully, please login!");
} catch (error) {console.log(error);}}
return alert("Please enter your new Password");
}
return (
<div>
<h2> Change Password </h2>
<form>
<label /> New Password:
<input
type="password"
placeholder="........"
required=""
value={password}
onChange={(e) => setPassword(e.target.value)} />
<button onClick={() => changePassword()}>Reset passwod </button>
</form>
</div>
);
}
Mã này hiển thị một biểu mẫu cho phép người dùng nhập mật khẩu mới. Khi người dùng nhấp vào gửi, nó sẽ gửi yêu cầu đến máy chủ để cập nhật mật khẩu của họ trong cơ sở dữ liệu. Sau đó, nó sẽ cập nhật giao diện người dùng nếu yêu cầu thành công.
Cập nhật Thành phần App.js của bạn
Thực hiện các thay đổi bên dưới đối với tệp src/App.js của bạn:
import { useState, createContext } from "react";
import Login from "./components/Login";
import OTPInput from "./components/OTPInput";
import Reset from "./components/Reset";
import "./App.css";
export const RecoveryContext = createContext();export default function App() {
const [page, setPage] = useState("login");
const [email, setEmail] = useState("");
const [otp, setOTP] = useState("");
function NavigateComponents() {
if (page === "login") return <Login />;
if (page === "otp") return <OTPInput />;
if (page === "reset") return <Reset />;
}
return (
<div className="App-header">
<RecoveryContext.Provider
value={{ page, setPage, otp, setOTP, email, setEmail }}>
<div>
<NavigateComponents />
</div>
</RecoveryContext.Provider>
</div>
);
}
Mã này xác định một đối tượng ngữ cảnh quản lý trạng thái của ứng dụng, bao gồm email của người dùng, mã OTP và các trang khác nhau trong ứng dụng. Về cơ bản, đối tượng bối cảnh có thể chuyển các trạng thái bắt buộc giữa các thành phần khác nhau—một giải pháp thay thế cho việc sử dụng đạo cụ.
Nó cũng bao gồm một chức năng xử lý điều hướng trang một cách dễ dàng mà không cần kết xuất lại toàn bộ thành phần.
Thiết lập máy chủ Express.js
Với thiết lập máy khách, hãy định cấu hình dịch vụ xác thực phụ trợ để xử lý chức năng đặt lại mật khẩu.
Để bắt đầu, hãy tạo một máy chủ web Express và cài đặt các gói sau:
npm install cors dotenv nodemailer mongoose
Tiếp theo, tạo cơ sở dữ liệu MongoDB hoặc định cấu hình cụm MongoDB trên đám mây. Sau đó sao chép chuỗi kết nối được cung cấp, tạo tệp ENV trong thư mục gốc và dán chuỗi kết nối.
Để hoàn tất, bạn cần định cấu hình kết nối cơ sở dữ liệu và xác định mô hình dữ liệu cho dữ liệu người dùng của mình. Sử dụng mã trong kho lưu trữ này để thiết lập kết nối cơ sở dữ liệu và xác định các mô hình dữ liệu.
Xác định các tuyến API
Dịch vụ phụ trợ lý tưởng là có một số tuyến xử lý các yêu cầu HTTP của khách hàng. Trong trường hợp này, bạn sẽ cần xác định ba tuyến sẽ quản lý các yêu cầu gửi email, xác minh email và cập nhật mật khẩu API từ ứng dụng khách React.
Tạo một tệp mới có tên userRoutes.js trong thư mục gốc và thêm đoạn mã sau:
const express = require('express');
const router = express.Router();
const userControllers = require('../controllers/userControllers');router.get('/check_email', userControllers.checkEmail);
router.put('/update-password', userControllers.updatePassword);
router.post('/send_email', userControllers.sendEmail);
module.exports = router;
Bộ điều khiển cho các tuyến API
Bộ điều khiển chịu trách nhiệm xử lý các yêu cầu HTTP của khách hàng. Sau khi khách hàng đưa ra yêu cầu đối với một tuyến API cụ thể, chức năng của bộ điều khiển sẽ được gọi và thực thi để xử lý yêu cầu và trả về phản hồi thích hợp.
Tạo một cái mới bộ điều khiển/userControllers.js tập tin và thêm mã dưới đây.
Sử dụng mã trong kho lưu trữ này để xác định bộ điều khiển cho các tuyến API xác minh email và cập nhật mật khẩu.
Bắt đầu bằng cách xác định bộ điều khiển gửi email:
exports.sendEmail = (req, res) => {
const transporter = nodemailer.createTransport({
service: 'gmail',
secure: true,
auth: {
user: process.env.MY_EMAIL,
pass: process.env.APP_PASSWORD,
},
}); const { recipient_email, OTP } = req.body;
const mailOptions = {
from: process.env.MY_EMAIL,
to: recipient_email,
subject: 'PASSWORD RESET',
html: `<html>
<body>
<h2>Password Recovery</h2>
<p>Use this OTP to reset your password. OTP is valid for 1 minute</p>
<h3>${OTP}</h3>
</body>
</html>`,
};
transporter.sendMail(mailOptions, (error, info) => {
if (error) {
console.log(error);
res.status(500).send({ message: "An error occurred while sending the email" });
} else {
console.log('Email sent: ' + info.response);
res.status(200).send({ message: "Email sent successfully" });
}
});
};
Mã này xác định một chức năng sử dụng Nodemailer để gửi email có đặt lại OTP tới một người nhận được chỉ định. Nó thiết lập một trình vận chuyển bằng tài khoản và mật khẩu Gmail của riêng bạn.
Để lấy mật khẩu ứng dụng Gmail, bạn cần tạo mật khẩu ứng dụng trong cài đặt tài khoản Google của mình. Sau đó, bạn sẽ sử dụng mật khẩu này thay cho mật khẩu Gmail thông thường của mình để xác thực Nodemailer.
Định cấu hình Điểm vào máy chủ
Tạo tệp server.js trong thư mục gốc và thêm mã này:
const express = require('express');
const cors = require('cors');
const app = express();
const port = 5000;
require('dotenv').config();
const nodemailer = require('nodemailer');
const connectDB = require('./utils/dbconfig');
connectDB();
app.use(express.json());
app.use(express.urlencoded({ extended: true }));
app.use(cors());
const userRoutes = require('./routes/userRoutes');
app.use("https://www.smartreviewaz.com/", userRoutes);app.listen(port, () => {
console.log(`Server is listening at http://localhost:${port}`);
});
Với cả máy khách và máy chủ được thiết lập, bạn có thể chạy các máy chủ phát triển để kiểm tra chức năng mật khẩu.
Xây dựng dịch vụ đặt lại mật khẩu tùy chỉnh
Tạo một hệ thống đặt lại mật khẩu bằng cách điều chỉnh nó cho phù hợp với ứng dụng của bạn và người dùng của nó là cách tiếp cận tốt nhất, mặc dù vẫn tồn tại các giải pháp dựng sẵn, trả phí. Trong khi thiết kế tính năng này, bạn nên tính đến cả trải nghiệm người dùng và bảo mật vì các cuộc tấn công là mối đe dọa thường xuyên.