굿즈 스토어 프로젝트 03-1 - 로그인 기본.

이유승·2023년 7월 19일
0

다음은 로그인 기능의 구현이다.



1. 에러 모달창.

입력값을 받아서 함수를 호출 할 때 인자로 넘긴다는 기본적인 구조는 회원가입 기능과 동일하다. 가입할 때 중복 검사를 실시했으니 로그인 할 때에는 유효성 검사만 실행해주면 된다.

하나 달라진 것은 이전부터 계속 문제가 되었던 '에러 처리가 미흡하다'는 문제를 보강하기 위해 에러 모달창을 제작하였다는 것.

입력값이 이메일 형식에 맞지 않으면 회원가입때와 마찬가지로 경고창만을 출력하지만, 아예 가입되지 않은 이메일을 입력할 경우에는..

위와 같이 에러 모달창이 따로 출력되도록 구현하였다.

에러 발생을 관리하는 방법은 플래그 변수. Action Creator에서 기능이 동작할 때, 에러가 발생할 경우 에러가 발생했을 때 미리 지정해둔 동작을 dispatch하도록 만든다.

catch (error) {
	dispatch({ type: 'ERROR', payload: createErrorData(error) });
};

(...)

// 에러 발생.
case 'ERROR':
	draft.flagvalue.isError = true;
	draft.flagvalue.isLoading = false;
	draft.errorinfo.errorCode = action.payload.errorCode;
	draft.errorinfo.errorMessage = action.payload.errorMessage;
	break;
    

그러면 Reducer를 통해 Redux Store의 에러 관리용 플래그 state 'isError'를 포함해 필요한 값들을 갱신해주게 된다.

const [isError, setIsError] = useState(false);

(...)

// Redux Store에서 State가 갱신될 때마다, 당 컴포넌트의 플래그 변수도 갱신되도록.
useEffect(() => {
    setIsError(getUserState.flagvalue.isError);
    setIsLoading(getUserState.flagvalue.isLoading);
    // eslint-disable-next-line
}, [getUserState.flagvalue]);

Store의 State가 갱신되면 프론트에서는 이를 감지하여 프론트에 선언한 에러 플래그 변수를 조정한다.

{/* 에러 상황 시에만 렌더링되는 에러 모달 창. */}
<ErrorModal isError={isError} getUserState={getUserState} onClickError={onClickError} />

에러 모달창은 isError 변수가 true일 때만 display 속성이 none이 아니도록 구현하면 에러가 발생했을 때만 모달창이 출력되도록 할 수 있다.

display: ${(props) => props.isError ? 'flex' : 'none'};



2. 로그인/로그아웃 UI와 기능.

사실 이전 프로젝트의 UI 및 기능과 비교해 볼 때, 에러 모달창을 구현한 것 이외에는 이번 프로젝트와 별 차이점이 존재하지 않는다. 원래는 비밀번호 부분에 대해서는 암호화 개념을 도입하려고 했는데, 웹 보안 쪽에 대해 제대로 공부해본 적이 없어서 결국 라이브러리 하나를 가져와서 암호화하고 복호화하는 수준에 불과하다보니 제대로 이번 프로젝트에서는 사용을 보류했다.

나중에 이 쪽에 대해 더 공부해보고 다음 프로젝트 때 적용해볼 생각이다.

// 회원가입 기능
router.post("/register", (req, res) => {
    // 프론트단에서 입력된 아이디와 비밀번호, 이름 및 이메일을 받아와준다.
    const { memberid, memberpw, membername, memberemail } = req.body;

    // 받아온 비밀번호를 암호화한다. 또한 hash가 실행될 숫자를 지정해준다. (높을수록 많이 진행되지만 소모 시간도 길어진다.)
    bcrypt.hash(memberpw, 10)
    // 암호화가 완료될 경우 아래 코드가 실행된다.
    .then((hash) => {
    	(...) 
    }
    
    (...) 

   // 아이디가 존재한다면 이제 로그인 과정으로 넘어가야한다.
   // 다음 순서로는 비밀번호를 검증해야 한다. 우선 ID 검증을 위해 조회한 결과값에서 Password값을 가져온다.
   const dbpwd = result[0].MEMBER_PW;
   // DB에 저장된 비밀번호는 bcrypt에 의해 암호화된 상태로, 단순한 1:1 비교는 불가능하다.
   // 그렇기에 bcrypt에 내장된 대조기능을 사용하여 비밀번호를 검증한다.
   bcrypt.compare(memberpw, dbpwd)
   // 검증이 완료되었을 경우 아래 코드를 실행한다.

예전에 Express.js로 백엔드를 구현해서 만들었던 프로젝트가 하나 있었는데 거기서도 암호화 부분은 bcrypt 모듈에서 제공하는 암호화 기능 등을 그냥 사용했던 것 뿐이라.. 웹 보안에 대해서 뭐라도 공부를 하는게 먼저인 것 같다.

코드 평가.

평가 방법, 개인적인 코드 리뷰 및 Chat GPT 사용.

-> 로그인 폼의 구체화? Formik 또는 React Hook Form과 같은 폼 라이브러리를 사용하여 폼 처리와 유효성 검사를 간소화할 수 있다고 한다. 사실 많은 경우에서 내가 직접 구현하는 것 보다 나보다 아는게 많은 사람들이 만들어둔 라이브러리를 사용하는게 낫긴 하다. 이게 공부 목적의 프로젝트라 라이브러리 사용을 최소화 하는게 목적이라 직접 구현한 것이지만..

profile
프론트엔드 개발자를 준비하고 있습니다.

1개의 댓글

comment-user-thumbnail
2023년 7월 19일

이렇게 유익한 내용을 공유해주셔서 감사합니다.

답글 달기