mysql2/promise 모듈을 활용해 로그인 페이지를 완성해보자.
mysql2/promise 모듈 (+ promise)
이전 포스트에서 정리한 mysql2 모듈의 createPool 메서드를 활용해 AWS RDS와 연동해보겠습니다. (AWS RDS는 이전에 만들어둔 것 활용하겠습니다.)
- 설치
1
npm i mysql2
Pool 생성
Model 폴더에 새로운 model_user.js
파일을 생성합니다.
mysql2/promise 패키지를 import
한 후 createPool 메서드
를 사용해 Pool을 생성합니다.
getConnection 메서드
로 Connection을 가져와 쿼리 작업을 한 후 반환합니다.
1
2
3
4
5
6
7
8
9
10
11
12
import mysql from "mysql2/promise";
const pool = await mysql.createPool({
host: "db-instance.czm29ewy6sqk.ap-northeast-2.rds.amazonaws.com", //실제로 연결할 데이터베이스의 위치
user: "psmin",
password: "java1994",
database: "user", //데이터베이스 이름
port: 3306,
connectionLimit: 30,
});
const conn = await pool.getConnection(async (conn) => conn);
로그인 기능 구현
Controller로 부터 사용자의 id를 받아 연동된 AWS RDS에 저장된 사용자 정보를 조회합니다.
해당 데이터가 존재하면 객체로 반환하고 존재하지 않으면 에러를 반환합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
... // Pool 생성
class UserStorage {
static async getUserInfo(id) {
try {
const sql = "SELECT id, password FROM users WHERE id = ?";
await conn.beginTransaction();
const [rows] = await conn.query(sql, [id]);
await conn.commit();
return rows[0];
} catch (err) {
await conn.rollback();
throw err;
} finally {
conn.release();
}
}
}
export default UserStorage;
회원가입 기능 구현
Controller로 부터 사용자가 보낸 id, password, name을 객체로 받아 연동된 AWS RDS에 사용자 정보를 추가합니다.
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
... // Pool 생성
class UserStorage {
static async getUserInfo(id) {
... // 로그인 기능
}
static async createUser(userInfo) {
try {
const sql = "INSERT INTO users(id, password, nickname) VALUES(?, ?, ?);";
await conn.beginTransaction();
await conn.query(sql, [userInfo.id, userInfo.password, userInfo.name]);
await conn.commit();
return { success: true }; // 쿼리 성공 시 반환
} catch (err) {
await conn.rollback();
throw err;
} finally {
conn.release();
}
}
}
export default UserStorage;
Controller 수정
사용자가 로그인 요청 시 아이디가 틀렸을 경우 Error가 발생하므로 try-catch문 으로 처리해줍니다.
사용자가 회원가입 요청 시 req.body (id, password, name 이 담긴 객체)를 인수로 넘깁니다.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import UserStorage from "../models/model_user.js";
const output = {
login: (req, res) => {
res.render("user/login");
},
register: async (req, res) => {
res.render("user/register");
},
};
const process = {
login: async (req, res) => {
var response = {};
try {
const user = await UserStorage.getUserInfo(req.body.id);
if (user) {
if (password === req.body.password) {
return (response = { success: true });
} else {
return (response = { success: false, msg: "비밀번호가 틀렸습니다." });
}
}
response = { success: false, msg: "존재하지 않는 아이디입니다." };
} catch (err) {
response = {
success: false,
msg: "로그인을 할 수 없습니다.\n잠시 후 다시 시도해주세요.",
};
} finally {
res.json(response);
}
},
register: async (req, res) => {
try {
const user = await UserStorage.getUserInfo(req.body.id);
let response = {};
if (user) {
return (response = { success: false, msg: "아이디가 존재합니다." });
}
response = await UserStorage.createUser(req.body);
res.json(response);
} catch (err) {
// 간단한 에러 처리문 작성
const response = {
success: false,
msg: "회원가입을 할 수 없습니다.\n 잠시 후 다시 시도해주세요.",
};
} finally {
res.json(response);
}
},
};
export default { output, process };
Pool & Connection 생성 모둘화
Model_user.js
에서 createPool, getConnection 부분을 config 폴더에 따로 담아두고 필요할 때 꺼내서 사용해 코드의 가독성을 높혀보겠습니다.
config폴더에 db_pool.js
파일에 Pool을 생성하고 Connection을 받아 export합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import mysql from "mysql2/promise";
const pool = await mysql.createPool({
host: process.env.DB_HOST, //실제로 연결할 데이터베이스의 위치
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE, //데이터베이스 이름
port: process.env.DB_PORT,
connectionLimit: process.env.DB_CONN_LIMIT,
});
const conn = await pool.getConnection(async (conn) => conn);
export default conn;
model 파일에 db_pool.js 파일을 import하고 필요할 때 사용하고 쿼리 작업 완료 후 반환합니다.
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
import conn from "../config/db_pool.js";
class UserStorage {
static async getUserInfo(id) {
try {
const sql = "SELECT id, password FROM users WHERE id = ?";
await conn.beginTransaction(); // 커넥션을 받아 트랜잭션 시작
const [rows] = await conn.query(sql, [id]);
await conn.commit(); // 쿼리문 완료시 커밋
return rows[0];
} catch (err) {
await conn.rollback(); // 에러 발생 시 롤백
throw err;
} finally {
conn.release(); // 쿼리 작업 완료 후 반환
}
}
static async createUser(userInfo) {
...
}
}
export default UserStorage;