2월 23일 자 학습 내용 정리입니다.
✅ crypto
crypto는 Node.js의 기본 모듈로 OpenSSL의 해시, HMAC, 암호, 해독, 서명 및 확인 등의 암호화 기능을 제공한다.
회원가입 기능 구현 시 회원의 비밀번호를 그대로 데이터베이스에 저장하게 되면 관리자가 모든 회원의 비밀번호를 알 수 있고 탈취가 일어날 수 있어 보안 취약점이 발생한다.
따라서 이 경우 hash를 이용한다.
hash는 문자열을 되돌릴 수 없는 방식으로 암호화하는 방법이다.
해시 함수는 임의의 길이의 데이터를 고정된 길이의 데이터로 매핑하는데 이 결과로 얻어진 해시 값은 원래의 형태로 되돌릴 수 없다.
회원가입 구현 시 hash를 이용하는 방법은 다음과 같다.
- 입력받은 비밀번호의 hash 값을 데이터베이스에 저장한다.
- 이후 로그인 시 입력받은 비밀번호의 hash 값을 구하고 데이터베이스에 저장된 비밀번호의 hash 값과 비교한다.
let crypto;
try {
crypto = await import('crypto');
} catch (err) {
console.log('crypto support is disabled!');
}
const hash = crypto.createHash('sha1');
hash.update(password);
hash.digest('hex');
crypto에서는 간단하게 sha1 알고리즘을 사용하거나 보다 강력한 sha224, sha256 등의 알고리즘을 사용할 수 있다.
✏️ 예제 - 회원가입 구현하기
회원가입을 구현하는 방식은 다음과 같다.
- 회원가입 페이지 구현
- 이메일 형식, 비밀번호 확인 문자 확인
- post 요청 전송
- 회원가입 처리 및 redirect
✔️ 회원가입 페이지 구현
...
form(action="/join" method="post" onsubmit="return check()")
table
tbody
tr
td 이메일
td: input(type="text" name="email")
tr
td 이름
td: input(type="name" name="name")
tr
td 비밀번호
td: input(type="password" name="password")
tr
td 비밀번호 확인
td: input(type="password" name="password_confirm")
tr
td(colspan="2")
input(type="submit" value="가입하기")
...
회원가입 페이지를 구현한 코드이다.
POST 요청을 보내기 위해 form을 사용했고 입력받을 이메일, 이름, 비밀번호, 비밀번호 확인 칸을 생성했다.
✔️ 유효 값 체크
...
script.
function check() {
const email = document.querySelector('[name="email"]').value;
if (!/^\S+@\S+\.\S+$/.test(email)) {
alert('이메일 형식이 올바르지 않습니다.');
return false;
}
const password = document.querySelector('[name="password"]').value;
if (password.length < 8) {
alert("최소 8자리 이상의 비밀번호를 설정해 주세요.");
return false;
}
const passwordConfirm = document.querySelector('[name="password_confirm"]').value;
if (password != passwordConfirm) {
alert('비밀번호 확인이 일치하지 않습니다.');
return true;
}
return false;
}
이후 script에서 입력받은 값들이 유효한 값인지 확인한다.
email은 xxx@xxxx.xxxx의 값인지, password는 8 이상의 길이를 가지고 있는지, passwordConfirm이 입력한 비밀번호와 일치하는지 판별한다.
form을 새로고침 하지 않기 위해 모두 유효한 값을 가질 경우 false를 리턴한다.
✔️ 회원가입 요청 처리
...
router.post(url, async(req, res) => {
const { email, name, password } = req.body;
const pwHash = getHash(password);
const exists = await User.findOne({ email });
if (exists) {
throw new Error('이미 가입된 메일입니다');
}
await User.create({
email,
name,
password: pwHash,
});
res.redirect('/');
});
...
POST 요청이 들어오면 입력으로 들어온 email, name, password를 받아온다.
그리고 password는 암호화시킨다.
id로 사용될 이메일은 유일해야 하기 때문에 이미 회원가입을 한 이메일인지 확인한 후 존재하는 이메일일 경우 에러를 반환한다.
email이 존재하지 않는 경우 정상적으로 회원가입 절차를 진행하며 User에 email, name, password를 저장한다.
이때 password는 암호화된 값으로 저장한다.
이 과정까지 모두 끝났다면 회원가입이 끝났다는 의미로 사용자를 메인 화면으로 redirect 시킨다.
🔍 참조
crypto https://nodejs.org/api/crypto.html#determining-if-crypto-support-is-unavailable
해시 함수 https://ko.wikipedia.org/wiki/%ED%95%B4%EC%8B%9C_%ED%95%A8%EC%88%98
'엘리스 AI 트랙 4기 > elice AI track' 카테고리의 다른 글
[6주차] Session과 Session Store (0) | 2022.02.23 |
---|---|
[6주차] Passport.js와 로그인 구현하기 (0) | 2022.02.23 |
[5주차] Express.js + Mongoose로 Pagination 구현하기 (0) | 2022.02.19 |
[5주차] Pug와 Async Request Handler, PM2 (0) | 2022.02.19 |
[5주차] Mongoose ODM - (2) (0) | 2022.02.19 |
댓글