본문 바로가기

환영합니다. 이 블로그 번째 방문자입니다.
프로젝트 일지

[🐾 일지] 리액트 프로젝트 회원가입 서버 연결 (Axios 400번 에러)

원래 fetch()를 썼었으나 axios를 많이 쓴다고 해서 처음으로 사용하게 되었다.

axios 공식문서를 보고 처음에 호기롭게 시도했으나 콘솔에 가득한 빨간줄...프로젝트 생명이 위험함


제일 많이 났던 400번 에러에 대해 작성해보려고 한다.

일단, 내가 하는 프로젝트는 회원가입 로직이 조금 복잡하다. 사실 복잡하지 않은데 처음해봐서 복잡하게 느껴졌다.

 

 

 [로직] step 1 

회원가입시 보내는 정보 

url method data (body)
http://localhost:3000/api/user/create post nickName, email, pw, profilePicture, location

 

회원가입 서버 연결 시 반환된 상태와 메세지에 따른 다음 수행작업

status message next step
200 성공 해당 이메일로 인증번호 발송
400 실패 내 잘못 
403 이메일 인증을 하지 않음  안내 메세지 -> 해당 이메일로 인증번호 발송
409 이미 유일값을 가진 유저가 존재 안내 메세지 -> 다시 회원가입을 하도록 함

 

 

 

 

 

 

 

 [로직] step 2 

인증번호 발송시 보내는 정보

url method data (body)
http://localhost:3000/api/user/sendauthemail post email

 

인증번호 발송시 반환된 상태와 메세지에 따른 다음 수행작업

status message next step
200 성공 인증번호 확인
400 실패 내 잘못 
500 서버 내의 문제 발생 서버 잘못

 

 

 

 

 

 

 

  [로직] step 3 

인증번호 확인시 보내는 정보

url method data (body)
http://localhost:3000/api/user/compareauthemail post email, authString

 

인증번호 확인시 반환된 상태와 메세지에 따른 다음 수행작업

status message next step
200 성공 로그인 페이지로 라우팅
400 실패 내 잘못 
401 인증번호가 일치하지 않음 인증번호 재전송 or 재입력 창 띄우기
404 부여된 인증번호가 없음 누구의 잘못도 아님

 

 


 

 

 [구현] step 0 

데이터를 송신할 때마다 axios를 import 하기보다는 utils 폴더에 API 컴포넌트를 만들어 export 하였다.

 

import axios from 'axios';

const API = axios.create({
    baseURL: 'http://localhost:3000/api',
    headers: {
        'Content-Type': 'application/json',
    },
});

export default API;

 

baseURL에 저렇게 넣어두고 사용할 수 있다는 것이 가장 큰 장점이다.

 

 

 

 

 

 

 

 [구현] step 1 

회원가입 axios post 로 생성하기

회원가입 input 정보를 나는 다음과 같이 받았다. location은 받지 않기로 확정된 내용이라 따로 받지 않았다.

 

const [profile, setProfile] = useState('');
const [info, setInfo] = useState({
    nickName: '',
    email: '',
    pw: '',
    passwordConfirm: '',
});

 

인증번호 발송 버튼을 누를 시에 동작은 handleButton 으로 처리했다.

 

import { API, checkUserInfo } from 'utils';

const handleButton = () => {
	/* 입력 값의 형태가 올바른지 판별 */
        if (checkUserInfo(info.nickName, info.email, info.pw, setErrorMessage))
            return;
            
	/* 데이터 전송 */
        API.post('/user/create', {
        	nickName:info.nickName,
        	email:info.email,
        	pw:info.pw,
        	profilePicture: profile
            })
            .then((response) => {
                if (response.status === 200) {
                    const authEmail = { email: userData.email };
                }
            })
            .catch((error) => console.log(error.response));
    };

 

이렇게 해서 보냈더니 400번 오류가 계속 났다.

 

 

중간에 있는 net::ERR_SSL_PROTOCOL_ERROR 는 baseURL에 http가 아닌 https 를 써서 난 오류이다.

서버에서 설정한 '비밀번호 이상'이라는 메세지가 떠서 서버 코드를 확인해보았지만 찾을 수 없었다. 

 

const handleButton = () => {
        if (checkUserInfo(info.nickName, info.email, info.pw, setErrorMessage))
            return;
            
	/* 객체 생성 후 전송 */
        const userData = {
            nickName: info.nickName,
            email: info.email,
            pw: info.pw,
            profilePicture: profile,
        };


        API.post('/user/create', userData)
            .then((response) => {
                if (response.status === 200) {
                    const authEmail = { email: userData.email };
                }
            })
            .catch((error) => console.log(error.response));
    };

 

axios post body에 데이터를 일일히 보내지 않고 userData 객체를 생성해서 보냈더니 드디어 에러를 해결했고

데이터베이스에도 잘 들어간 걸 확인할 수 있었다. 

 

 

 

 

 

 

 

 [구현] step 2 

회원가입 후(정보가 잘 들어간 이후) 인증번호 보내기 

정보가 잘 들어갔다는 것을 확인하는 방법은 reponse.status === 200 일 때 밖에 없다. 따라서 해당 상태일 때에 맞는 정보를 맞는 url에 post 해주면 된다.

 

const sendAuthMail = async (email) => {
            await API.post('/user/sendauthemail', email)
                .then((res) => {
                    console.log(res);
                    if (res.status === 200) {
                        props.setEmail(email.email);
                        props.setShowSignup(false);
                        props.setShowEmailAuth(true);
                    } else if (res.status === 403) {
                        alert('you already signup');
                    }
                })
                .catch((err) => console.log(err.response));
        };

const handleButton = () => {
        if (checkUserInfo(info.nickName, info.email, info.pw, setErrorMessage))
            return;

        const userData = {
            nickName: info.nickName,
            email: info.email,
            pw: info.pw,
            profilePicture: profile,
        };

        API.post('/user/create', userData)
            .then((response) => {
                if (response.status === 200) {
                    const authEmail = { email: userData.email };
                    sendAuthMail(authEmail);
                }
            })
            .catch((error) => console.log(error.response));
    };

 

sendAuthMail 이라는 함수를 만들어 handleButton의 response.status === 200 일 때,

authEmail 객체를 생성해주고 sendAuthMail을 호출했다. 

 

 

 

 

 

 

 

 [구현] step 3 

sendAuthMail 의 response.status === 200 일때, 인증번호를 입력하는 화면을 띄어준다.

 

본인확인 화면
인증번호 입력

 

인증번호를 입력하고 확인 버튼을 누르면 인증번호 비교를 하는 함수를 호출한다.

 

const handleCompareButton = async () => {
        const authData = {
            email: props.email,
            authString: authCode,
        };

        await API.post('/user/compareauthemail', authData)
            .then((res) => {
                console.log(res);
                if (res.status === 200) {
                    alert('success');
                    props.setShowEmailAuth(false);
                    props.setShowLogin(true);
                } else if (res.status === 401) {
                    alert('no match');
                }
            })
            .catch((err) => console.error(err));
    };

 

이것도 마찬가지로 객체로 담아서 해당 url에 post하면 잘 되는 것을 볼 수 있다.

서버와 소통하는 함수들은 api 폴더에 index 파일에 분리해 작성하고 필요할 때마다 호출해 쓸 수 있도록 하였다.

 

 

 

 

 

 결론 

Axios 400번 Bad Request 에러 : post시에 body에 객체를 보내지 않을 경우 (잘못된 송신 방법) 일어난다.