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'; import idpwScreen from 'https://tistory3.daumcdn.net/tistory/2784544/skin/images/wd-searchFormScreen.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는 아이디, 비밀번호 찾기와 관련된 모듈을 중개하는 라우터 기능을 담당한다.
import { firebaseConfig } from "https://tistory1.daumcdn.net/tistory/2784544/skin/images/wd-utils.js";
import seekIDScreen from "https://tistory4.daumcdn.net/tistory/2784544/skin/images/wd-sub-searchIDScreen.js";
import seekPWScreen from "https://tistory2.daumcdn.net/tistory/2784544/skin/images/wd-sub-searchPWScreen.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"; 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에서 보낸 이메일 재설정 메일을 볼 수 있다.
'웹개발 자료실 > Firebase 개발 Code' 카테고리의 다른 글
블로그 회원가입 제작 [3편. 마이 페이지] (0) | 2022.01.10 |
---|---|
블로그 회원가입 제작 [2편. 회원가입 페이지] (0) | 2022.01.07 |
블로그 회원가입 제작(feat. firebase) [1편. 파이어베이스 설정 & 로그인폼 제작] (0) | 2022.01.06 |
Firebase『Auth 로그인, 비밀번호 찾기』 (1) | 2019.12.28 |
Firebase『Auth 회원가입, 이메일 인증,』 (10) | 2019.12.27 |
댓글