본문 바로가기

블로그 회원가입 제작 [4편. 아이디 비밀번호 찾기]

by Recstasy 2022. 1. 11.

 

https://webdoli.tistory.com/pages/ResetPW 에 접속했을 때, 아래와 같은 화면을 볼 수 있다.

 

[ 아이디, 비밀번호 찾기 ]

 

 


1 인터페이스 :: searchInterface.js

'아이디 찾기' , '비밀번호 찾기'를 선택할 수 있는 인터페이스를 구현한다. searchInterface.js는 사용자가 접속한 페이지가 resetPW인지 아닌지를 판단한다. url의 마지막 파라미터값이 resetPW일 경우에는 idpwScreen모듈을 실행한다.

 


   
import { parseRequestUrl, chkPage } from 'https://tistory1.daumcdn.net/tistory/2784544/skin/images/wd-utils2.js';
       
       
   window.addEventListener('load', async() => {

       const routes = {
           'ResetPW': idpwScreen,
           'Index': IndexScreen,
       }

       let userCurrentPage = await chkPage().then((page) => {
           return page;
       });

       const screen = routes[userCurrentPage] ? routes[userCurrentPage] : routes['Index'];
       const content = document.getElementById('content');
       content.innerHTML = await screen.render();
       if(screen.module_render) await screen.module_render();
       if(screen.after_render) await screen.after_render();
   });

[ searchInterface.js ]

 

 

 

 

 

 


2 라우터 :: searchFormScreen.js

searchFormScreen.js는 아이디, 비밀번호 찾기와 관련된 모듈을 중개하는 라우터 기능을 담당한다. 

 

 
 
  const config = firebaseConfig();
  const firebaseApp = initializeApp(config);
  const auth = getAuth();
  const routes = {
        'id-seek' : seekIDScreen,
        'pw-seek' : seekPWScreen,
    }
 
  const idpwScreen = {
   
      after_render: () =>{
          let userSlc = document.querySelectorAll('.btn-reset');
       
          userSlc.forEach(eachItem => {
              eachItem.addEventListener('click', async(e) => {
                  e.preventDefault();
                  let resetContent = document.getElementById('reset-content');
                if(resetContent.nextElementSibling) resetContent.nextElementSibling.remove();
               
                  let slc = e.target.getAttribute('reset');
                  resetContent.innerHTML = await routes[slc].render();
   
                if(routes[slc].after_render) await routes[slc].after_render(auth);
              })
          });
       
      },
 
      render: async() => {
          return `
        <div id="reset-container" style="border-bottom:1px solid lightGrey; padding:15px 5px;margin-bottom:40px;margin-top:-50px;">
            <div id="reset-header">
                <button class="btn-reset" reset="id-seek">아이디 찾기</button>
                <button class="btn-reset" reset="pw-seek">비밀번호 찾기</button>
            </div>
        </div>
        <div id="reset-content"></div>
          `
      }
  }
 
  export default idpwScreen;

[ searchFormScreen.js ]

 

 

 

 

 

 

 

 

 

 


3 랜더링 모듈

 3-1 searchIDScreen.js 

'아이디 찾기'는 firestore DB에서 이메일을 검색한 결과를 알려준다. mypage 구현에서 사용했던 getDOC, query, where 모듈을 재활용한다.  

 

[ 아이디 찾기 ]

 

 

query( )모듈에서 firebase DB의 이메일을 수집한 뒤에 onSnapshot( )모듈이 전달한 반환값에 따라 '일치 vs 불일치' 결과를 구현한다.

 


   
import { getFirestore, onSnapshot, collection, getDocs, query, where } from "https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js";
       
    const db = getFirestore();
    const seekIDScreen = {
        after_render: async(auth) =>{
            let btnUserEmail = document.getElementById('btn-user-seek-email');
            let resetContent = document.getElementById('reset-content');
       
            let btnEmailClk = await btnUserEmail.addEventListener('click' , async(e) =>{
                let usrEmailValue = document.getElementById('usr-seek-email').value;
                    
                const searchEmail = query(collection(db, "webdoliUsers"), where("email", "==", usrEmailValue));
                const docData = onSnapshot(searchEmail, (result) => {

                    if(result.empty){
                        if(resetContent.nextElementSibling) resetContent.nextElementSibling.remove();

                        let searchResEle = document.createElement('div');
                        searchResEle.className = 'searchError';
                        searchResEle.innerHTML = `<span>일치하는 이메일이 없습니다.</span>`;
                        resetContent.parentElement.appendChild(searchResEle);

                    }else{

                        if(resetContent.nextElementSibling) resetContent.nextElementSibling.remove();
                        let searchResEle = document.createElement('div');
                        searchResEle.className = 'searchSuccess';
                        result.forEach(item => {
                            searchResEle.innerHTML = `<span>이메일은 ${item.data().email} 입니다.</span>`;
                            resetContent.parentElement.appendChild(searchResEle);
                            return false;
                        })
                   
                    }
                });
           
            });
       
        },
   
        render: () => {
            return `
            <h3> 아이디 찾기 </h3>
            <div>
                <input type="email" id="usr-seek-email"/>
                <button type="submit" id="btn-user-seek-email">제출</button>
            </div>
            `
        }
    }
   
    export default seekIDScreen;

[ searchIDScreen.js ]

 

 

 

 

 3-2 searchPWScreen.js 

'비밀번호 찾기'는 firebase Auth 모듈 중에서 'sendPasswordResetEmail'을 참고한다. 무료 버전에서는 비밀번호 reset메일이 전송되는 속도가 1~2분 가량 소요된다. 하지만 테스트용으로는 꽤 쓸만하다.

 

[ 비밀번호 변경 ]


   
import { getFirestore, onSnapshot, collection, getDocs, query, where } from "https://www.gstatic.com/firebasejs/9.6.1/firebase-firestore.js";
    import { sendPasswordResetEmail } from "https://www.gstatic.com/firebasejs/9.6.1/firebase-auth.js";
       
    const db = getFirestore();
    const seekPWScreen = {
        after_render: (auth) =>{
           
            const searchPwdBtn = document.getElementById('forgot-password-button');
            searchPwdBtn.addEventListener('click', (e) => {
               
                    e.preventDefault();
                    let usrEmail = document.getElementById('forgot-password-email').value;
                    //유저 이메일 검증
                    let resetContent = document.getElementById('reset-content');
               
                    const searchEmail = query(collection(db, "webdoliUsers"), where("email", "==", usrEmail));
                    const docData = onSnapshot(searchEmail, (result) => {

                        if(result.empty){
                            if(resetContent.nextElementSibling) resetContent.nextElementSibling.remove();
                            let searchResEle = document.createElement('div');
                            searchResEle.className = 'searchError';
                            searchResEle.innerHTML = `<span>일치하는 이메일이 없습니다.</span>`;
                            searchResEle.style.marginLeft = '-75px';
                            resetContent.parentElement.appendChild(searchResEle);
                        }else{
                            if(resetContent.nextElementSibling) resetContent.nextElementSibling.remove();

                            sendPasswordResetEmail(auth, usrEmail)
                                .then(() => {
                                    alert('패스워드 재설정 메일이 발송되었습니다.');
                                    document.querySelector('.id-seek-formContainer').style.display = 'none'
                                    let endResEle = document.createElement('div');
                                    endResEle.className = 'pwSearchRes';
                                    endResEle.innerHTML = `<span>${usrEmail}을 확인해주세요. 1~2분 소요될 수 있습니다.</span>`;
                                    resetContent.parentElement.appendChild(endResEle);
                                    //DOM삭제 및 홈으로 이동 버튼 넣기
                                })
                                .catch(err => {
                                    console.log('error: '+ err.message);
                                })
                           
                        }
                    });
               
                    //이메일 검증 끝
               
                  });
        },
   
        render: async() => {
            return `
            <div class="id-seek-formContainer">
                <h3>비밀번호 찾기</h3>
                <form id="forgot-password-form">
                    <div id="forgot-password-inputs">
                        <p>이메일을 입력해주세요. </p>
                        <input id="forgot-password-email" class="modal-input" required autocomplete="off" type="email" placeholder="Email" />
                    </div>
                    <button id="forgot-password-button" class="purple-button auth-btn" type="submit">Send Recovery Email</button>
                </form>
            </div>
            `
        }
    }
   
    export default seekPWScreen;

[ searchPWScreen.js ]

 

 

 

 

 

 


4 CSS :: searchFormScreen.js

css파일이 필요하다면, 아래 코드를 붙여넣자.

 

  #container .content-wrap{
    margin-top: -350px;
  }
 
  #reset-container{
    display: flex;
    justify-content: center;
  }
 
  #reset-header{
    padding: 10px 10px;
  }
 
  #reset-header button{
    padding:10px 20px;
    background-color: #48CFAD;
    color: #fff;
    border-radius: 8px;
   
  }
 
  #reset-header button:nth-child(2){
    margin-left: 20px;
  }
 
  #reset-content{
    padding-top:20px;
    display: flex;
    justify-content: center;
    align-items: center;
  }
 
  #reset-content h3{
    font-size: 300;
  }
 
  #reset-content > div{
    margin-left: 15px;
  }
 
  #reset-content > div > input{
    padding: 5px 5px;
    border: 1px solid #979c9b;
   
  }
 
  #reset-content > div > button{
    margin-left: 10px;
    border: 1px solid #979c9b;
    padding: 5px 10px;
    background-color: #48CFAD;
    color:#fff;
    font-weight: 300;
  }
 
  .id-seek-formContainer h3{
    margin-bottom: 20px;
  }
 
  #forgot-password-inputs p{
    margin-bottom: 10px;
  }
 
  #forgot-password-email{
    padding:10px 10px;
    width: 270px;
  }
 
  #forgot-password-button{
    margin-top:10px;
    border: none;
    padding: 10px 5px;
    background-color: #48CFAD;
    box-shadow: 1px 2px 1px rgba(0, 0, 0, 0.5);
    font-size: 0.9rem;
    color: #fff;
  }
 
  .pwSearchRes{
    text-align: center;
  }
 
 
  .searchSuccess{
    margin-top: 10px;
    color:#48CFAD;
    text-align:center;
  }
 
  .searchError{
    margin-top: 10px;
    color:tomato;
    text-align:center;
  }

[ searchStyle.css ]

 

 

 

 

 

 

 

 

 


5 테스트 

alert( )에서 '확인'을 클릭하면 아래와 같은 화면이 나타난다.

 

 

위에서 입력한 이메일 편지함에서 firebase auth에서 보낸 이메일 재설정 메일을 볼 수 있다. 

 

 

 

 

댓글

최신글 전체

이미지
제목
글쓴이
등록일