소셜 로그인 마침.

Lee·2021년 3월 23일
0

3월 19일이 국비과정 (자바 웹개발 과정) 수료일이었고 3월 18일 새벽까지 마치지 못했던 소셜 로그인 기능 구현을 마쳤다.

백엔드로 토큰을 전송하여 사용자의 프로필 정보를 받아오는 것 까지는 성공했는데 localhost:3000(프론트엔드 주소)로 리다이렉트 시 가져온 정보를 실어보내는 것에 실패해 완전히 프론트엔드 만으로 구현하였다.(react-kakao-login, react-naver-login 모듈 사용)

많은 도움을 받은 블로그

  1. 그마저도 가져온 정보를 state에 저장하기 전에 DB를 탐색하여 해당 사용자의 아이디 정보가 없으면 가입절차를 진행하는 과정이 먼저 작동되어 애를 먹었다. sync 문제라고 생각하여 promise, async-await 모두 적용해봤는데 그래도 해결이 안 됐다.

  2. useConfirm을 사용하여 가입 과정 진입 전에 한 번 브레이크를 걸면 해결되지 않을까 하여 각 서버에서 토큰, 사용자 정보를 가져오는 컴포넌트와 별개로 useConfirm 컴포넌트를 구현해서 사용하였는데 그래도 sync가 맞지 않았다.

3.해결법은 useConfirm을 별도로 구현하는 것이 아닌 각 사용자 정보를 가져오는 컴포넌트에서 구현한 후 useEffect를 사용하는 것이었다!

(1) 사용자가 로그인을 하면
(2) payload로 사용자 정보를 받아서 state에 저장 후
(3) DB에 존재하는지 검색을 하고
(4) 존재하면 로그인 후 홈페이지로 이동, 존재하지 않으면 가입을 진행하겠냐는 confirm 팝업 발생, 가입 시 로그인 후 홈페이지로 이동

총 이런 과정이고

useEffect로 어떻게componentDidUpdate() 를 구현할 수 있을까 고민했는데 (useEffect는 조건으로 넣어주는 컴포넌트가 업데이트 될 때 뿐만 아니라 컴포넌트가 처음 mount 될 때에도 동작하기 때문에...)

참고 링크 를 참고하여 useEffect 작동에 조건에 조건식을 부여해서 해결했다.

1. success가 업데이트 될 때 DB에 사용자 아이디 존재 여부 체크

 const success = payload => {
    props.success(snsPayloadParser.NAVER(payload));

    setValues({
      ...values,
      user_id: snsPayloadParser.NAVER(payload).email,
      user_name: snsPayloadParser.NAVER(payload).name,
    })

    console.log(payload);
  };

  useEffect(()=>{
    if(values.user_id==""){
      return;
    }else{
      axios.get("/users/login", {
        params: {
          user_id: values.user_id,
          user_pwd: values.user_pwd,
        },
      })
      .then((res) => setSocialUser(res))
      .catch((err) => console.log(err)); } 
    }, [success])

  const fail = payload => {
    props.fail(payload);
  };

2. DB에 없으면 confirmAction동작, 있으면 Reducer의 user라는 state에 값 저장, cookie에 저장 후 홈페이지로 이동

const setSocialUser = (res) => {
    if (res.data == "") {
     return confirmAction();
    } else {
      return new Promise((resolve, reject) => {
        resolve(
          dispatch({
            type: "SET_USER",
            user: res.data,
          })
        );

        console.log(res);
        Cookies.set("user", res.data.user_sequence_id);

        history.push("/home");
       });
    }
  };

3. confirmAction

 const useConfirm = (message = "", event, cancel) => {
    if (typeof event !== "function") {
      return;
    }

    const confirmEvent = () => {
      if (window.confirm(message)) {
        event();
      } else {
        cancel();
      }
    };
    return confirmEvent;
  };

  const event = () => postForm(); 
  const cancel = () => alert("가입이 취소 되었습니다");
  const confirmAction = useConfirm("해당 계정 정보가 없습니다. 해당 계정으로 가입하시겠습니까?", event, cancel) 

'확인' 버튼 클릭 시 postForm() 동작.
'취소' 버튼 클릭 시 팝업창 닫힘.

4. PostForm()

const postForm = () => {        
    axios.post(`users`, values)
    .then(alert("가입이 완료되었습니다."))
    .then(res => setSocialUser(res))
    .catch(err => console.log(err))
}

postForm()은 동작 시 DB의 users테이블에 로그인 한 사용자의 정보를 저장하고 가입이 완료됐다는 alert창을 출력한 후 setSocialUser()를 동작하여 reducer의 user state에 사용자 정보를 저장, cookie에 사용자 정보를 저장한다.

카카오 로그인은 이렇게 연동까지 완료 되었는데 네이버 로그인은 localhost 환경에서만 정상 작동 되고 디플로이 된 실제 사용 사이트에서는 '등록되지 않은 웹사이트' 라는 callback 주소 불일치 오류로 의심되는 오류가 계속하여 발생중이다.

그래서 네이버 개발자 센터 포럼에 도움을 요청했는데 해결이 될지는 모르겠다...

아무튼 3월 18일 새벽 해당 기능을 완성하고 19일 오후에 무사히 프로젝트 시연, 해당 교육 과정 수료를 마칠 수 있었다.

profile
하고 싶은 게 너무 많습니다.

0개의 댓글