- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- JavaScript
- await
- TailwindCSS
- atlas
- jsonwebtoken
- sequelize
- async
- til
- double quote
- Node.js
- findByIdAndDelete
- mongodb
- mongoose
- certbot
- EC2
- single quote
- Nodejs
- css
- wil
- nginx
- AWS
- RDS
- MYSQL
- Find
- Express
- flutter
- TypeScript
- moment
- clipBehavior
- https
기억 휘발 방지소
[Node.js] bcrypt로 비밀번호를 보호하자 본문
📌 해시함수란?
해시함수(Hash Function)은 임의의 길이의 데이터를 고정된 길이의 데이터를 매핑하는 함수이다.
출처: 위키백과
해시함수는 단방향 암호화라고도 한다.
단방향 암호화란 A가 해시함수를 거쳐 B가 나왔다고 했을 때 B를 가지고 다시 A를 알아낼 수 없다! (반대의 개념으로 양방향 암호화가 있는데 양방향 암호화는 A를 B로 암호화하고 B를 다시 복호화하여 A를 알아낼 수 있다.)
또한 어떤 입력에 대해서 항상 같은 결과가 나온다.
보통 회원가입을 할 때 비밀번호를 DB에 저장할 때 해시함수를 거친 결과값을 DB에 저장한다.
그렇게 하면 DB를 누군가 해킹했을 때 해시함수를 갖고 비밀번호를 역으로 알아낼 수 없다!!
📌 bcrypt
bcrypt는 해시함수 중 하나이다.
자바스크립트 뿐만 아니라 C, C++, Java, Python 등 다양한 언어에서 사용할 수 있다.
설치
npm i bcrypt
📌 bcrypt로 비밀번호 암호화하기 - bcyrpt.hash
// User.js
import mongoose from "mongoose";
const userSchema = new mongoose.Schema({
email: { type: String, required: true, unique: true },
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
});
const User = mongoose.model("User", userSchema);
export default User;
아래 코드처럼 form으로 입력받은 실제 비밀번호를 DB에 그대로 저장하게 되면 비밀번호가 그대로 노출되기 때문에 암호화를 반드시 해야한다.
// userController.js
import User from "./models/User";
export const postJoin = async (req, res) => {
const { email, username, password } = req.body;
await User.create({
email,
username,
password,
});
return res.redirect("/login");
};
bcrypt로 해시를 만드는 함수는 다음과 같다.
유저가 입력한 패스워드가 myPlaintextPassword자리에 들어가며 saltRounds는 몇 번 해싱할건지를 의미한다.
bcrypt.hash(myPlaintextPassword, saltRounds, function(err, hash) {
// Store hash in your password DB.
});
async/await를 쓸 수도 있다.
async function checkUser(username, password) {
//... fetch user from a db etc.
const match = await bcrypt.hash(password, saltRounds);
//...
}
미들웨어에 bcrypt를 적용했다.
5번 해싱을 하도록 했다.
// User.js
import mongoose from "mongoose";
import bcrypt from "bcrypt";
const userSchema = new mongoose.Schema({
// ...
});
userSchema.pre("save", async function () {
console.log("Users password:", this.password);
this.password = await bcrypt.hash(this.password, 5);
console.log("Hashed password:", this.password);
});
// ...
결과를 보면 위가 유저가 입력한 값이고 아래가 해싱된 값이다.
Users password: 1234
Hashed password: $2b$05$GdBICVsSamyiYd8/UMxffuSeFTEniBM8BYTOmyJy9ZVCT8H3Eareu
📌 bcrypt.compare
DB에 실제 비밀번호가 아니라 해시값이 저장되어 있다. 그렇기 때문에 로그인할 때 실제 비밀번호가 아니라 해시값으로 비교를 해서 비밀번호 일치 여부를 따져봐야한다.
이때 bcrypt.compare를 사용해 비교하면 된다!
아래 코드처럼 사용하면 된다고한다.
async function checkUser(username, password) {
//... fetch user from a db etc.
const match = await bcrypt.compare(password, user.passwordHash);
if(match) {
//login
}
//...
}
예시
bcrypt.compare의 첫 번째 매개변수는 사용자가 입력한 비밀번호이고 두 번째 매개변수는 User.findOne으로 DB에서 검색한 user 데이터의 비밀번호를 넣어줘서 두 값을 비교하고 일치하면 true를 반환하고 일치하지 않으면 false를 반환하게 된다.
조건문으로 일치하지 비밀번호가 일치하지 않는 경우 처리할 일을 구현해줬다.
export const postLogin = async (req, res) => {
const { username, password } = req.body;
const user = await User.findOne({ username });
// ...
const ok = await bcrypt.compare(password, user.password);
if (!ok) {
// ...
}
return res.redirect("/");
};
'Web > Node.js' 카테고리의 다른 글
[Node.js] multer (0) | 2021.09.27 |
---|---|
[Node.js] express-session (0) | 2021.09.23 |
[Node.js] mongoDB Schema 생성 (0) | 2021.09.18 |
[Node.js] mongoDB를 연결해보자 (0) | 2021.09.17 |
[Node.js] express.urlencoded는 뭘까? (0) | 2021.09.16 |