REST api를 이용한 리액트 로그인 구현
본문 바로가기

React & React Native

REST api를 이용한 리액트 로그인 구현

728x90
반응형
소프트웨어 설치
  • Node.js
  • NPM
리액트 앱 만들기

먼저 create-react-app을 실행하여 새로운 리액트 프로젝트를 시작해준다.

npx create-react-app frontend

생성한 폴더로 접근한다.

cd frontend
패키지추가하기 (yarn 또는 npm)
  • Material UI
  • react-router-dom
  • Sweetalert
npm i @material-ui/core @material-ui/icons react-router-dom sweetalert

예제에서는 로그인에서 프로필 화면으로 전환되도록 라우터를 걸어주고 있다. 

 

 

 

axios로 API 통신을 이용하여 로그인을 구현한다. JWT 토큰 방식을 이용하여 로그인을 하는데, POST로 회원가입/로그인에 필요한 정보를 서버로 보내면 서버는 아이디 중복여부를, 로그인 시에는 정보 일치 여부를 확인하여 정보를 클라이언트에 전달한다. 클라이언트는 서버로부터 전달받은 정보를 redux에 저장하여 회원 서비스를 이용한다.

 

🍰 JWT 로그인 인증방식에 대하여 궁금하다면

 

JWT 로그인 인증방식

개요 HTTP 기본 인증 방식이 모바일에서는 raw한 api키를 매 요청 때마다 사용해야 하는 문제가 있어 취약점 공격에 노출될 가능성이 높다. 또한 API 키가 내장된 채로 배포하면 리버싱을 통해 API 키

velog.io

 

코드

로그인 컴포넌트

//LoginPage.js

/*생략*/
const [id, setId] = React.useState("");
const [pwd, setPwd] = React.useState("");

/*생략*/

const LoginPage = () => {
//입력 값 정합성 체크 후 login API 요청
    if (id === "" || pwd === "") {
      window.alert("아이디와 비밀번호를 입력해주세요.");
      return;
    }
    if (!emailCheck(id)) {
      window.alert("이메일 형식이 맞지 않습니다.");
    }
    dispatch(userActions.loginDB(id, pwd));
  };

/*생략*/

 <Input
            _onChange={(e) => {
              setId(e.target.value);
            }}
            width="380px"
            height="45px"
            placeholder="아이디"
          />
          <Input
            _onChange={(e) => {
              setPwd(e.target.value);
            }}
            width="380px"
            height="45px"
            placeholder="비밀번호"
            type="password"
          />

 

리덕스 모듈 api 통신

//UserPage.js (Redux module)

//API통신을 통해 서버에 id,pwd를 제공하고 유저 정보와 토큰을 받아 저장
const loginDB = (id, password) => {
  return function (dispatch, getState, { history }) {
    axios({
      method: "post",
      url: "http://13.125.249.241/user/login",
      data: {
        email: id,
        password: password,
      },
    })
      .then((res) => {
        console.log(res);
        dispatch(
          setUser({
            email: res.data.email,
            nickname: res.data.nickname,
          })
        );
        const accessToken = res.data.token;
        //쿠키에 토큰 저장
        setCookie("is_login", `${accessToken}`);
        document.location.href = "/";
      })
      .catch((error) => {
        console.log(error);
      });
  };
};

//회원가입 API
const signUpDB = (id, password, nickname) => {
  return function (dispatch, getState, { history }) {
    axios({
      method: "post",
      url: "http://13.125.249.241/user/signup",
      data: {
        email: id,
        password: password,
        nickname: nickname,
      },
    })
      .then((res) => {
        window.alert(res.data.result);
      })
      .catch((error) => {
        console.log(error);
      });
  };
};

 

자동 로그인

로그인시에 DB에서 가져온 사용자 정보는 리덕스에 저장을 시켜두기 때문에 리로드가 발생하면 초기화가 된다. 그렇기 때문에 페이지 재접속시 사용자 정보를 넣어주는 작업이 필요하다.

  • 쿠키에 JWT 토큰이 저장되었는지 확인
  • JWT 토큰을 서버에 보내 유효성 및 사용자 검증 요청
  • 검증 성공시 서버가 응답한 로그인 정보로 업데이트
//MainPage.js
...
 React.useEffect(() => {
     
     //쿠키에 저장된 액세스 토큰이 존재할 때만 서버에 검증 요청
    if(getCookie("is_login")){
      dispatch(userActions.loginCheckDB());
    }
    
  }, []);
...
//UserPage.js (Redux module)
...
//로그인 유지 API
//서버에서 토큰을 받아 유효성 검증 후 사용자 정보를 내려주어 로그인 상태 유지
const loginCheckDB = () => {
  return function (dispatch, getState, { history }) {
    const token = getCookie("is_login");
    axios({
      method: "post",
      url: "http://13.125.249.241/user/check",
      headers: {
        Authorization: `Bearer ${token}`,
      },
    })
      .then((res) => { 
        dispatch(
          setUser({
            email: res.data.email,
            nickname: res.data.nickname,
          })
        );
      })
      .catch((error) => {
        console.log(error.code, error.message);
      });
  };
};

 

⚠️ CORS 에러

로컬에서 api를 호출을 하려니 CORS 에러가 난다. 아래 블로그를 참고해서 잡아준다.

 

CORS는 서로 다른 출처간 리소스를 전달하는 방식을 제어하는 체제로 CORS 요청이 가능하려면 서버에서 특정 헤더인 Access-Control-Allow-Origin과 함께 응답할 필요가 있다.

 

레퍼런스

 

나를 너무나 힘들게 했던 CORS 에러 해결하기 😂

🔥 사건의 발단 : 외부 API 호출 때는 바야흐로 2020년 3월. 프론트엔드 공부를 시작한 지 얼마 되지 않은 채 홀로 토이 프로젝트를 진행하던 중이었다. 코로나 바이러스 관련 웹서비스를 만들고자

xiubindev.tistory.com


실행하기
npm start

 

이제 단계별로 메인 페이지, 상품 페이지, 마이 페이지, 장바구니 등등을 구현하면 된다.

 


레퍼런스

 

반응형