개인프로젝트/기능프로그램_오늘뭐입지

20240530 모놀리틱)_ajax, 이메일인증 및 submit 제약

일일일코_장민기 2024. 5. 31. 16:49
728x90

 

전체 코드

더보기

React

import React, {useEffect, useState} from "react";
import {NavLink, useNavigate} from "react-router-dom";
import axios from "axios";

function RegisterPage() {
    const [username, setUsername] = useState("");
    const [password, setPassword] = useState("");
    const [email, setEmail] = useState("");
    const [country, setCountry] = useState("");
    const [area, setArea] = useState("");
    const navigate = useNavigate();
    const [countryList, setCountryList] = useState([]);
    const [areaList, setAreaList] = useState([]);
    const [existUsername, setExistUsername] = useState("");
    const [existEmail, setExistEmail] = useState("");
    const [checkAuthorizationCodeField, setCheckAuthorizationCodeField] = useState("");
    const [code, setCode] = useState("");

    useEffect(() => {
        fetch("/findCountries").then((response) => {
            return response.json();
        }).then(function (result) {
            console.log(result)
            setCountryList(result)
            if (result.length > 0) {
                setCountry(result[0]);
            }
        })
    }, []);
    useEffect(() => {
        fetch(`/findAreasByCountry?country=${country}`).then((response) => {
            return response.json();
        }).then(function (result) {
            console.log(result)
            setAreaList(result);
        })
    }, [country]);
    const usernameAjax = async (event) => {
        const newUsername = event.target.value;
        setUsername(newUsername);
        axios.defaults.withCredentials = true;
        try {
            const response = await axios.post(`/usernameAjax?username=${newUsername}`, {}, {
                headers: {
                    "Content-Type": "application/json"
                }
            });
            if (response.status === 200) {
                console.log(response.data);
                if (response.data === true) {
                    setExistUsername("아이디 중복");
                } else {
                    setExistUsername("");
                }
            }
        } catch (error) {
            console.error(error);
        }
    }
    const emailAjax = async (event) => {
        const newEmail = event.target.value;
        setEmail(newEmail)
        axios.defaults.withCredentials = true;
        try {
            const response = await axios.post(`/emailAjax?email=${newEmail}`, {}, {
                headers: {
                    "Content-Type": "application/json"
                }
            });
            if (response.status === 200) {
                console.log(response.data)
                if (response.data === true) {
                    setExistEmail("이메일 중복")
                } else {
                    setExistEmail("")
                }
            }
        } catch (error) {
            console.error(error)
        }
    }
    const emailAuthorizationCode = async (event) => {
        axios.defaults.withCredentials = true;
        try {
            const response = await axios.post(`/emailAuthorizationCode?email=${email}`, {}, {
                headers: {
                    "Content-Type": "application/json"
                }
            });
            if (response.status === 200) {
                console.log(response.data)
                alert("인증번호가 메일로 전송되었습니다.")
            }
        } catch (error) {
            console.error(error)
        }
    }
    const codeAjax = async (event) => {
        const newCode = event.target.value;
        console.log("newCode: ", newCode)
        setCode(newCode);
        const cookies = document.cookie;    //모든 쿠키 가져오기
        const cookieArray = cookies.split(";") //모든 쿠키를 배열로 만들기
        const authorizeCookie = cookieArray.map(cookie => cookie.split("=")).find(([name]) => name === "authorizationCode");
        console.log(authorizeCookie)
        if (authorizeCookie[1] === newCode.toString()) {
            setCheckAuthorizationCodeField("확인되었습니다.")
        } else {
            setCheckAuthorizationCodeField("인증번호 오류")
        }
    }
    const handleSubmit = async (event) => {
        event.preventDefault();
        let errorMessage = '';
        switch (true) {
            case    existUsername === "아이디 중복":
                errorMessage = '아이디 중복 상태입니다.'
                break;
            case    existEmail === "이메일 중복":
                errorMessage = '이메일 중복 상태입니다.'
                break;
            case    checkAuthorizationCodeField === "인증번호 오류":
                errorMessage = '코드 불일치 상태입니다.'
                break;
            default:
                axios.defaults.withCredentials = true;
                try {
                    const response = await axios.post("/saveUser", {
                        username: username,
                        password: password,
                        email: email,
                        country: country,
                        area: area
                    }, {
                        headers: {
                            "Content-Type": "application/json"
                        }
                    });
                    if (response.status === 200) {
                        navigate("/LoginPage")
                    } else {
                        navigate("/RegisterPage")
                    }
                } catch (error) {
                    console.error("Error: ", error);
                }
        }
        if(errorMessage !== ""){
            alert(errorMessage);
        }
    }

    return (
        <div>
            <form id="registerForm" onSubmit={handleSubmit}>
                username:
                <input type="text" id="username" name="username" value={username}
                       onChange={usernameAjax}
                       required minLength="3"/><br/>
                <span id="existUsername">{existUsername}</span><br/>

                password:
                <input type="text" id="password" name="password" value={password}
                       onChange={(event) => setPassword(event.target.value)} required minLength="3"/><br/>

                email:
                <input type="email" id="email" name="email" value={email}
                       onChange={emailAjax}
                       required minLength="3"/><br/>
                <span id="existEmail">{existEmail}</span><br/>

                인증번호:
                <input type="text" id="authorizationCode" onChange={codeAjax}/>
                <input type="button" id="sendEmail" value="인증번호 보내기" onClick={emailAuthorizationCode}/><br/>
                <span id="checkAuthorizationCodeField">{checkAuthorizationCodeField}</span><br/>

                country:
                <select id="country" value={country} onChange={(event) => setCountry(event.target.value)}>
                    {countryList.map((country, index) => (
                        <option key={index} value={country}>{country}</option>
                    ))}
                </select><br/>

                area:
                <select id="area" value={area} onChange={(event) => setArea(event.target.value)}>
                    {areaList.map((area, index) => (
                        <option key={index} value={area}>{area}</option>
                    ))}
                </select>
                <input type="submit" value="회원가입"/>
            </form>
            <p>
                <NavLink to="/loginPage">로그인 페이지</NavLink>
            </p>
        </div>
    )
}

export default RegisterPage;

 

 Java

RestController

package org.example.beforeLogin;

import jakarta.servlet.http.HttpServletResponse;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.example.mailController.MailController;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RestController;

import java.io.IOException;

@RestController
@RequiredArgsConstructor
@Slf4j
public class BeforeLoginRestController {

    private final BeforeLoginService beforeLoginService;
    private final MailController mailController;

    @PostMapping("/usernameAjax")
    public ResponseEntity<Boolean> usernameAjax(String username) {
        return ResponseEntity.ok(beforeLoginService.usernameAjax(username));
    }

    @PostMapping("/emailAjax")
    public ResponseEntity<Boolean> emailAjax(String email) {
        return ResponseEntity.ok(beforeLoginService.emailAjax(email));
    }

    @PostMapping("/emailAuthorizationCode")
    public ResponseEntity<Boolean> emailAuthorizationCode(String email, HttpServletResponse httpServletResponse) throws IOException {
        log.info("emailAuthorizationCode: {}", email);
        mailController.mailCookie(httpServletResponse);
        mailController.authorizationCode_Email(email);
        return ResponseEntity.ok(true);
    }
}

 

username ajax

 

useState 설정

const [username, setUsername] = useState("");
const [existUsername, setExistUsername] = useState("");

 

- username은 현재 입력된 아이디를 저장하고 출력하는 변수

- existUsername은 현재 입력된 아이디가 중복된 아이디인지를 출력하기 위해 경고를 저장하고 출력하는 변수

 

return 설정

<input type="text" id="username" name="username" value={username}
       onChange={usernameAjax}
       required minLength="3"/><br/>
<span id="existUsername">{existUsername}</span><br/>

- onChange를 통해 입력할 때마다 ajax를 사용

- ajax의 결과값은 {existUsername} 을 통해 출력

- value={username}은 없어도 상관없음

 

axios 설정

const usernameAjax = async (event) => {
    const newUsername = event.target.value;
    setUsername(newUsername);
    axios.defaults.withCredentials = true;
    try {
        const response = await axios.post(`/usernameAjax?username=${newUsername}`, {}, {
            headers: {
                "Content-Type": "application/json"
            }
        });
        if (response.status === 200) {
            console.log(response.data);
            if (response.data === true) {
                setExistUsername("아이디 중복");
            } else {
                setExistUsername("");
            }
        }
    } catch (error) {
        console.error(error);
    }
}

- event.target.value를 통해 현재 입력한 username을 부르고, newUsername이라는 변수에 저장

- newUsername에 저장한 변수를 useState를 사용하기 위해 setUsername

- cors 처리를 위해 axios.defaults.withCredentials = true;

 

const response = await axios.post(`/usernameAjax?username=${newUsername}`

- post 타입으로 java에 username 전송하고 데이터를 response라는 변수로 받아옴

 

 

쿠키값과 비교하는 ajax

const codeAjax = async (event) => {
    const newCode = event.target.value;
    console.log("newCode: ", newCode)
    setCode(newCode);
    const cookies = document.cookie;    //모든 쿠키 가져오기
    const cookieArray = cookies.split(";") //모든 쿠키를 배열로 만들기
    const authorizeCookie = cookieArray.map(cookie => cookie.split("=")).find(([name]) => name === "authorizationCode");
    console.log(authorizeCookie)
    if (authorizeCookie[1] === newCode.toString()) {
        setCheckAuthorizationCodeField("확인되었습니다.")
    } else {
        setCheckAuthorizationCodeField("인증번호 오류")
    }
}