بازدیدکنندگان سایت خود را معطل نگذارید – اگر رمز عبور خود را فراموش کرده اند، اجازه دهید آنها را بازنشانی کنند.
سیستم های احراز هویت نقش مهمی در ارائه یک تجربه کاربری یکپارچه و ایمن دارند. گردش کار احراز هویت معمولاً شامل دو فرآیند است: ثبت نام و ورود به سیستم.
با افزایش تعداد سرویسهای آنلاین، افراد حسابهایی ایجاد میکنند و هر حساب کاربری به اعتبارنامههای ورود منحصربهفرد نیاز دارد. با این حال، این باعث میشود که اعتبارنامههای ورود به سیستم فراموش یا اشتباه گرفته شود. برای رفع این مشکل، برنامه شما باید یک ویژگی بازنشانی رمز عبور را اجرا کند که به کاربر اجازه می دهد رمز عبور خود را به راحتی و ایمن بازنشانی کند.
پروژه React را راه اندازی کنید
شما می توانید یک گردش کار بازنشانی رمز عبور را به روش های مختلف پیاده سازی کنید—یک استاندارد جهانی وجود ندارد که هر برنامه ای باید از آن پیروی کند. در عوض، باید رویکردی را که انتخاب میکنید برای برآورده کردن نیازهای خاص برنامه خود تنظیم کنید.
گردش کاری که در اینجا با آن آشنا می شوید شامل مراحل زیر است:
برای شروع، به سرعت یک پروژه React را بوت استرپ کنید. سپس، Axios را نصب کنید، یک کتابخانه درخواست HTTP جاوا اسکریپت.
npm install axios
می توانید کد پروژه را در این مخزن GitHub پیدا کنید.
یک مؤلفه ورود ایجاد کنید
در پوشه src، یک فایل components/Login.js جدید ایجاد کنید و کد زیر را اضافه کنید. با تعریف فرآیند بازنشانی رمز عبور شروع کنید:
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");
}}
این کد تابعی را ایجاد می کند که یک رمز عبور یکبار مصرف (OTP) را به آدرس ایمیل کاربر ارسال می کند. ابتدا کاربر را با بررسی ایمیل او در پایگاه داده قبل از تولید و ارسال OTP تأیید می کند. در نهایت، UI را با صفحه OTP به روز می کند.
مولفه ورود را با افزودن کد برای رندر کردن عنصر فرم ورود به سیستم JSX تکمیل کنید:
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>
);
}
یک مؤلفه تأیید OTP ایجاد کنید
برای اطمینان از اعتبار کد وارد شده توسط کاربر، باید آن را با کد ارسال شده به ایمیل او مقایسه کنید.
یک فایل components/OTPInput.js جدید ایجاد کنید و این کد را اضافه کنید:
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");
}
}
کد یک مؤلفه React ایجاد می کند که در آن کاربران کد OTP خود را تأیید می کنند. بررسی می کند که کد وارد شده با کد ذخیره شده در شی متن مطابقت داشته باشد. اگر معتبر باشد، صفحه بازنشانی رمز عبور را نمایش می دهد. برعکس، هشداری را نشان می دهد که از کاربر می خواهد دوباره امتحان کند یا OTP را دوباره ارسال کند.
میتوانید کد موجود در این مخزن را بررسی کنید که تابعی را برای ارسال مجدد OTPها و یک تایمر انقضا برای کد OTP اجرا میکند.
در نهایت عناصر ورودی JSX را رندر کنید.
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>
);}
مولفه Reset Password را ایجاد کنید
یک فایل components/Reset.js جدید ایجاد کنید و این کد را اضافه کنید:
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>
);
}
این کد فرمی را ارائه می دهد که به کاربران امکان می دهد رمز عبور جدید را وارد کنند. هنگامی که کاربر بر روی ارسال کلیک می کند، درخواستی برای به روز رسانی رمز عبور خود در پایگاه داده به سرور ارسال می کند. سپس در صورت موفقیت آمیز بودن درخواست، UI را به روز می کند.
کامپوننت App.js خود را به روز کنید
تغییرات زیر را در فایل src/App.js خود اعمال کنید:
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>
);
}
این کد یک شی زمینه را تعریف می کند که وضعیت برنامه را مدیریت می کند که شامل ایمیل کاربر، کد OTP و صفحات مختلف داخل برنامه است. اساساً، شیء زمینه، انتقال حالتهای مورد نیاز بین اجزای مختلف را ممکن میسازد – جایگزینی برای استفاده از props.
همچنین دارای عملکردی است که به راحتی پیمایش صفحه را بدون نیاز به رندر کردن مجدد کل اجزا انجام می دهد.
یک سرور Express.js راه اندازی کنید
با راه اندازی سرویس گیرنده، یک سرویس احراز هویت پشتیبان را برای مدیریت عملکرد بازنشانی رمز عبور پیکربندی کنید.
برای شروع، یک وب سرور Express ایجاد کنید و این بسته ها را نصب کنید:
npm install cors dotenv nodemailer mongoose
بعد، یک پایگاه داده MongoDB ایجاد کنید یا یک خوشه MongoDB را روی ابر پیکربندی کنید. سپس رشته اتصال ارائه شده را کپی کنید، یک فایل ENV در دایرکتوری ریشه ایجاد کنید و رشته اتصال را Paste کنید.
برای اتمام، باید اتصال پایگاه داده را پیکربندی کنید و مدل های داده را برای داده های کاربر خود تعریف کنید. از کد موجود در این مخزن برای راه اندازی اتصال پایگاه داده و تعریف مدل های داده استفاده کنید.
مسیرهای API را تعریف کنید
یک سرویس Backend به طور ایده آل دارای چندین مسیر است که درخواست های HTTP مشتریان را مدیریت می کند. در این مورد، باید سه مسیر را تعریف کنید که درخواستهای ارسال ایمیل، تأیید ایمیل و درخواستهای API بهروزرسانی رمز عبور از مشتری React را مدیریت میکنند.
یک فایل جدید به نام userRoutes.js در پوشه اصلی ایجاد کنید و کد زیر را اضافه کنید:
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;
کنترلرهای مسیرهای API
کنترلرها مسئول پردازش درخواست های HTTP مشتریان هستند. هنگامی که یک کلاینت به یک مسیر API خاص درخواست می دهد، یک تابع کنترل کننده فراخوانی و اجرا می شود تا درخواست را پردازش کند و پاسخ مناسب را بازگرداند.
یک فایل controllers/userControllers.js جدید ایجاد کنید و کد زیر را اضافه کنید.
از کد موجود در این مخزن برای تعریف کنترلرهایی برای مسیرهای API تأیید ایمیل و به روز رسانی رمز عبور استفاده کنید.
با تعریف کنترلر ارسال ایمیل شروع کنید:
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" });
}
});
};
این کد تابعی را تعریف می کند که از Nodemailer برای ارسال ایمیل با بازنشانی OTP به یک گیرنده مشخص استفاده می کند. با استفاده از حساب جیمیل و رمز عبور خود، یک انتقال دهنده راه اندازی می کند.
برای دریافت رمز عبور برنامه Gmail خود، باید یک رمز عبور برنامه را در تنظیمات حساب Google خود ایجاد کنید. سپس از این رمز عبور به جای رمز عبور معمولی جیمیل خود برای احراز هویت Nodemailer استفاده خواهید کرد.
نقطه ورودی سرور را پیکربندی کنید
یک فایل server.js در پوشه اصلی ایجاد کنید و این کد را اضافه کنید:
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('/', userRoutes);
app.listen(port, () => {
console.log(`Server is listening at http://localhost:${port}`);
});
با راه اندازی سرویس گیرنده و سرور، می توانید سرورهای توسعه را برای آزمایش عملکرد رمز عبور اجرا کنید.
ساخت یک سرویس بازنشانی رمز عبور سفارشی
ایجاد یک سیستم بازنشانی رمز عبور با تطبیق آن با برنامه شما و کاربرانش بهترین رویکرد است، حتی اگر راه حل های از پیش ساخته شده پولی وجود داشته باشد. هنگام طراحی این ویژگی، باید هم تجربه کاربری و هم امنیت را در نظر بگیرید، زیرا حملات یک تهدید دائمی هستند.