티스토리 뷰

▶계정 찾기 및 탈퇴 기능 구현

지난번에 회원가입과 로그인 기능을 구현해 보았었는데요🙂

이번에는 회원가입 시 데이터베이스에 저장된 정보들을 가지고 계정(아이디) 찾기와 탈퇴 기능을 구현해 보도록 하겠습니다.

 

🔎 계정 찾기


📌 계정 찾기 화면 구성

이메일을 입력해서 검색하기 버튼을 누르면 그 이메일을 사용하고 있는 계정의 아이디를 보여주게 됩니다.

 

회원 이메일 입력하면 → 아이디 알려주기

없는 회원 이메일 입력하면 → 계정이 존재하지 않다고 알려주기

계정 찾기 화면 구성

 

📌 데이터베이스에 있는 데이터를 무엇을 어떻게 활용?

클라이언트에서 사용자가 입력한 이메일을 서버에게 보내면

서버는 그 이메일를 이용하여 데이터베이스에서 조회를 하게 되고, 조회가 된다면 그 조회된 값에서 아이디 값만 다시 클라이언트에게 보내면 됩니다.

만약 조회되는 값이 없다면 바로 클라이언트에게 'fail'이라는 결과값을 보내주면 됩니다.

users 테이블

 

 

📌 클라이언트 → 서버 : 입력받은 이메일 정보를 보내자

화면 컴포넌트를 구성하는 건 간단하니 바로 서버와 api 통신하는 부분을 바로 봅시다.

 

📄 Identify.jsx 파일

export default function Identify(props) {
  const [email, setEmail] = useState("");
  
  // ...
  
  const onClickSearch = () => {
    // 유효성 검사를 하고...
    
    axios.get('/api/identify', { params: { email } })
      .then(res => {
        const { result, text } = res.data;
        if (result === 'fail' && text) {
          alert(text);
        } else {
          alert('계정은' + result + '입니다.');
        }
      });
  };
  return (
    <div className="identify-layer">
      <div class="logo-box">
        <Image src={IMG_LOGO} alt="로고" />
      </div>
      <div class="card-box">
        <div class="head">
          <Title text="내 계정 찾기" />
        </div>
        <div class="body">
          <Subtitle text="계정을 검색하려면 이메일 주소 또는 휴대폰 번호를 입력하세요." />
          <Input
            type="text"
            placeholder="이메일 입력하세요"
            onChange={onChangeEmail}
          />
        </div>
        <div class="foot">
          <Button type="secondary" text="취소" onClick={onClickCnacel} />
          <Button type="primary" text="검색" onClick={onClickSearch} />
        </div>
      </div>
    </div>
  );
}

서버에서는 res.data에 result와 text를 실어서 보낼텐데,

만약 result가 fail이고 text도 같이 보내왔다면 그 text를 alert창으로 띄웁니다.

만약 그렇지 않다면 서버가 보내온 result(사용자의 아이디 값)을 alert창에 띄웁니다.

 

클라이언트가 api요청을 보낸 주소에 맞게 서버에서도 코드를 작성해 줍시다.

 

📌 서버 → 클라이언트 : 알려준 이메일로 데이터베이스 조회해 봤고, 그 결과는 이랬어

클라이언트에서 보내온 이메일 값을 이용하여 데이터베이스 조회를 하려고 합니다.

만약 조회되는 값이 있다면 그 값의 userid 값만 가져와 다시 클라이언트에게 보내고,

만약 조회되는 값이 없다면 fail과 찾을 수 없다는 text도 같이 클라이언트에게 보내줍니다.

 

 

📄 src/api/index.js 파일

router.get('/identify', async (req, res) => {
  const { email } = req.query;
  
  const user = await mysql.findAccountid({ email: email });
  
  if (user) {
    // 조회되는 사용자 값이 있다면
    res.send({ result: user.userId });
  } else {
    res.send({ result: 'fail', text: '계정이 존재하지 않습니다.' });
  }
});

이제는 알다싶이 다시 maria.js 파일로 가서 findAccountid라는 메서드를 잘 만들어주기만 하면 끝입니다.

 

📄 src/api/maria.js 파일

Maria.findAccountid = (params) => {
  return new Promise(async (resolve) => {
    const { email } = params;
    
    const sql = `select * from users where email='${email}';`;
    const result = await queryFunc(sql);
    resolve(result);
  })
}

 

728x90

 

🔎 회원 탈퇴


📌 회원 탈퇴 화면 구성

아래와 같이 사용자 아이디와 이메일 주소를 알려주고 탈퇴 버튼을 누르면 회원 탈퇴가 되도록 화면을 구성해 두었습니다.

(비밀번호나 생년월일 정보 확인 등으로도 개인 정보를 확인하여 더욱 엄격하게 회원 탈퇴가 이뤄지도록 할 수도 있겠네요..!)

회원 탈퇴 화면 구성

 

📌 데이터베이스에 있는 데이터를 무엇을 어떻게 활용?

클라이언트는 사용자가 입력한 아이디와 이메일 값을 서버에게 보내주게 되면

서버는 그 값을 가지고 데이터베이스를 조회하게 될 겁니다.

조회되는 값이 있다면 그 값을 조건식으로 하여 해당 데이터를 delete하면 되고

조회되는 값이 없다면 바로 클라이언트에게 실패했다고 알려주면 되겠습니다.

 

📌클라이언트 → 서버 : 입력받은 아이디와 이메일 값 보내줄게

이번에도 화면 구성은 간단하니 바로 api 통신하는 부분을 살펴봅시다.

 

📄 DeleteUser.jsx 파일

export defualt function DeleteUser(props) {
  const [userid, setUserid] = useState('');
  const [email, setEmail] = useState('');
  
  // ...
  
  const onClickOk = () => {
    // 유효성 검사 하고...
    
    axios.delete('/api/user', { params: { email: email, userid: userid } })
      .then(res => {
        const { reuslt } = res.data;
        
        if (result === 'success') {
          alert('회원탈퇴가 정상적으로 처리되었습니다.');
          window.location.href = '/';
        } else {
          alert('회원탈퇴가 처리되지 못했습니다. 잠시후 다시 이용해주세요.');
        }
      });
  };
  return (
    <div className="identify-layer delete-user-layer">
      <div className="logo-box">
        <Image src={IMG_LOGO} alt="로고" />
      </div>
      <div className="card-box">
        <div className="head">
          <Title text="회원탈퇴" />
        </div>
        <div className="body">
          <Subtitle text="계정을 삭제하려면 확인을 위해 계정 아이디와 이메일 주소를 입력하세요." />
          <Input
            type="text"
            name="userid"
            placeholder="계정 아이디"
            onChange={onChangeUserid}
          />
          <Input
            type="text"
            name="email"
            placeholder="이메일 주소"
            onChange={onChangeEmail}
          />
        </div>
        <div className="foot">
          <Button type="secondary" text="취소" onClick={onClickCancel} />
          <Button type="primary" text="탈퇴" onClick={onClickOk} />
        </div>
      </div>
    </div>
  );
}

클라이언트가 api 요청을 보낸 주소를 보고 이제 서버에서도 코드를 작성해 줍시다.

 

SMALL

 

📌 서버 → 클라이언트 : 알려준 값들로 delete 해봤는데, 그 결과를 보내줄게

📄 src/api/index.js 파일

router.delete('/user', async (req,res) => {
  const { email, userid } = req.query;
  
  const result = await mysql.deleteUser({ email: email, userid: userid });
  
  if (result) {
    // result === true
    res.send({ result: 'success' });
  } else {
    res.send({ result: 'fail' });
  }
});

maria.js 파일로 가서 deleteUser 메서드를 정의해 주면 되겠죠?

 

📄 src/api/maria.js 파일

Maria.deleteUser = (params) => {
  const { userid, email } = params;
  const sql = `delete from users where userid='${userid}' and email='${email}';`;
  
  const result = await queryFunc(sql);
  resolve(result && result.affectedRows === 1 ?  true : false);
}

affectedRows는 방금 실행된 쿼리문에 영향을 받은 줄 수(데이터의 열 수)를 의미합니다.

따라서 affectedRows === 1 로 조건을 추가하여 쿼리문이 성공적으로 적용이 되었음을 확인하도록 합니다.

 

만약 affectedRows 조건이 없다면 KEY가 중복되어 수행된 경우에도 성공적으로 회원탈퇴가 이루어졌다고 클라이언트에게 알려줄 것이므로 되도록이면 추가해주는 것이 좋겠습니다.

 

이것으로 회원탈퇴 기능도 끝입니다😀!

728x90
LIST
250x250
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함