"일꾼이 일을 잘하려면 먼저 도구를 갈고 닦아야 한다." - 공자, 『논어』.
첫 장 > 프로그램 작성 > 비밀번호 재설정 기능: 프런트엔드

비밀번호 재설정 기능: 프런트엔드

2024-11-01에 게시됨
검색:211

Password Reset Feature: Frontend

프런트엔드

프런트엔드 부분은 백엔드 부분에 비해 매우 쉽습니다. 내가 해야 할 일은 모달을 만들고 이를 사용하여 데이터를 두 번 보내는 것뿐입니다.

  • 먼저 OTP를 보낼 이메일을 보내세요.
  • 그런 다음 OTP와 새 비밀번호를 보내 변경하세요.

모달을 생성하기 위해 이전 프로젝트 Chat-Nat의 MessageModal 구성 요소에서 모달 캡슐화를 위한 classNames라는 일부 코드를 복사했습니다.

계획

'비밀번호를 잊으셨나요?'를 추가하겠습니다. 로그인 페이지의 버튼을 클릭하고 모달을 열도록 onClick 핸들러를 설정합니다

OTP를 요청하기 전에 사용자의 이메일로 OTP가 전송되었는지 여부를 나타내기 위해 부울 상태를 사용해야 합니다. 저는 상태 이름을 isOTPSent

로 지정하겠습니다.
  • !isOTPSent인 경우 -> 이메일 주소를 요청하고 API 요청을 보낸 다음 성공하면 setOTPSent(true)
  • isOTPSent인 경우 -> 이제 OTP와 새 비밀번호도 요청하고, 성공하면 모달을 닫습니다.

다음은 이 프로젝트의 기존 프런트엔드에서 재사용하는 몇 가지 구성 요소와 후크입니다.

  • 상자 -> 로그인 및 등록 페이지를 페이지 중앙에 있는 카드에 깔끔하게 포장하고 여기에서 "비밀번호 재설정"이라는 제목으로 재사용합니다.
  • AuthForm -> 단순한 양식이지만 서버의 응답을 기다릴 때 제출 버튼을 비활성화하고 버튼 텍스트를 "로드 중..."으로 설정하도록 코딩했습니다.
  • FormInput -> 자체 레이블이 있는 입력 필드, 값 설정기와 onChange 핸들러, 선택적으로 isRequired 부울 포함
  • useAxios -> 토큰 새로 고침이 필요한 서버의 응답을 처리하기 위한 사용자 정의 후크입니다. 일반 요청 전송을 위한 apiReq 함수, 경고() 및 새로 고침 토큰을 표시하는 일부 사용자 정의 오류 처리, 인증 토큰을 새로 고치고 초기 요청을 다시 시도하는 RefreshReq 함수.

모달의 전체 코드는 다음과 같습니다.

// src/components/PasswordResetModal.tsx
import React, { useState } from "react"
import AuthForm from "./AuthForm";
import FormInput from "./FormInput";
import Box from "./Box";
import { useAxios } from "../hooks/useAxios";

interface FormData {
    email: string,
    new_password: string,
    otp: string,
}

interface Props {
    isVisible: boolean,
    onClose: () => void,
}

const PasswordResetModal: React.FC = ({ isVisible, onClose }) => {
    const [formData, setFormData] = useState({
        email: "",
        new_password: "",
        otp: ""
    });
    const [isLoading, setLoading] = useState(false);
    const [isOTPSent, setOTPSent] = useState(false);
    const { apiReq } = useAxios();

    const handleClose = (e: React.MouseEvent) => {
        if ((e.target as HTMLElement).id === "wrapper") {
            onClose();

            // could have setOTPSent(false), but avoiding it in case user misclicks outside
        }
    };

    const handleChange = (e: React.ChangeEvent) => {
        const { name, value } = e.target;
        setFormData({
            ...formData,
            [name]: value,
        });
    };

    const handleSubmit = async (e: React.FormEvent) => {
        e.preventDefault();
        setLoading(true);

        if (!isOTPSent) { // first request for sending otp,
            const response = await apiReq("post", "/api/reset-password", formData)

            if (response) {
                alert("OTP has been sent to your email");
                setOTPSent(true);
            }
        } else { // then using otp to change password
            const response = await apiReq("put", "/api/reset-password", formData)

            if (response) {
                alert("Password has been successfully reset\nPlease log in again");

                // clear the form
                setFormData({
                    email: "",
                    otp: "",
                    new_password: "",
                })

                // close modal
                onClose();
            }
        }

        setLoading(false);
    };

    if (!isVisible) return null;

    return (
        
{isOTPSent && ( >)}
) } export default PasswordResetModal

로그인 양식에서 모달의 조건부 렌더링이 처리되는 방법은 다음과 같습니다.

// src/pages/auth/Login.tsx
import PasswordResetModal from "../../components/PasswordResetModal";

const Login: React.FC = () => {
    const [showModal, setShowModal] = useState(false);

    return (
        
{/* link to the register page here */} setShowModal(false)} />
)

끝났습니다! 아니면 그렇게 생각했어요.

개발 환경에서 앱을 실행하던 중 백엔드를 오랫동안 실행한 경우 이메일이 전달되지 않는 버그를 발견했습니다.

다음 게시물에서 이 버그를 수정하겠습니다.

릴리스 선언문 이 글은 https://dev.to/bitorsic/3-password-reset-feature-frontend-3623?1에서 복제됩니다.1 침해 내용이 있는 경우, [email protected]으로 연락하여 삭제하시기 바랍니다.
최신 튜토리얼 더>

부인 성명: 제공된 모든 리소스는 부분적으로 인터넷에서 가져온 것입니다. 귀하의 저작권이나 기타 권리 및 이익이 침해된 경우 자세한 이유를 설명하고 저작권 또는 권리 및 이익에 대한 증거를 제공한 후 이메일([email protected])로 보내주십시오. 최대한 빨리 처리해 드리겠습니다.

Copyright© 2022 湘ICP备2022001581号-3