쿠키와 세션을 활용해 자동 로그인 기능을 구현해보자.
유저 정보 페이지 만들기
간단하게 사용자의 이름을 전달받으면 줄력해주는 페이지를 만들고 Router에 추가해줍니다.
로그아웃 기능도 같이 추가해줍니다.
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
<!-- info.ejs -->
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="shortcut icon" href="#" />
<!-- CSS link -->
<link rel="stylesheet" href="/css/user/login.css" />
<title>메인 페이지</title>
</head>
<body>
<div class="login-page">
<div>
<% if (name) { %>
<ul>
<li><p>유저 정보</p></li>
<li><%= name %>님</li>
<li><a href="/user/logout">Logout</a></li>
</ul>
<% } else { %>
<a href="/user/login">Login</a>
<% } %>
</div>
</div>
<!-- script 삽입 -->
</body>
</html>
<!-- Copyright (c) 2022 by Aigars Silkalns (https://codepen.io/colorlib/pen/rxddKy) -->
1
2
3
4
5
6
7
8
9
10
11
12
13
// routes/route_user.js
...
Router.get("/info", ctrl.output.info);
Router.get("/login", ctrl.output.login);
Router.get("/register", ctrl.output.register);
Router.get("/logout", ctrl.process.logout);
Router.post("/login", validator_user.login, ctrl.process.login);
Router.post("/register", validator_user.register, ctrl.process.register);
export default Router;
쿠키와 세션으로 기능 구현
cookie-parser 모듈과 express-session 모듈을 활용합니다.
먼저
app.js
파일에cookie-parser 모듈
을 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 29
import express from "express"; import path from "path"; import "dotenv/config"; import bodyParser from "body-parser"; import cookieParser from "cookie-parser"; import userRouter from "./src/routes/route_user.js"; const app = express(); const __dirname = path.resolve(); // 앱 세팅 app.set("views", "./src/views"); app.set("view engine", "ejs"); // 미들웨어 app.use("/", express.static(`${__dirname}/src/public`)); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(cookieParser(process.env.COOKIE_SECRET)); // cookieParser 메서드에 인자로 주어지는 secret은 환경변수로 따로 관리합니다. // router app.use("/user", userRouter); // 3000 포트로 서버 오픈 app.listen(3000, () => { console.log("express server on port 3000"); });
session은 config 폴더에
session.js
파일을 만들어 모듈화해서 사용하겠습니다.세션 스토어로 Mysql을 사용하기 위해 express-mysql-session 모듈을 설치해 사용합니다.
참고 글 : express-session 모듈
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
import session from "express-session"; import mysqlStore from "express-mysql-session"; const mysqlStoreSession = mysqlStore(session); const options = { host: process.env.DB_HOST, //실제로 연결할 데이터베이스의 위치 user: process.env.DB_USER, password: process.env.DB_PASSWORD, port: process.env.DB_PORT, database: process.env.DB_DATABASE, clearExpired: true, // 만료된 세션 자동 삭제 기능 checkExpirationInterval: 30 * 60 * 1000, // 30분 ,만료된 세션이 지워지는 빈도 (밀리초) createDatabaseTable: true, expiration: 1 * 60 * 60 * 1000, // 1시간, 유효한 세션의 최대 시간 (밀리초) schema: { tableName: "sessions", columnNames: { session_id: "session_id", expires: "expires", data: "data", }, }, }; const sessionStore = new mysqlStoreSession(options); sessionStore .onReady() .then(() => { // 세션 스토어 준비 완료 console.log("MySQLStore ready"); }) .catch((err) => { // 에러 발생 console.error(err); }); export default session({ secure: true, // https 환경에서만 session 정보 처리 secret: process.env.COOKIE_SECRET, // 암호화하는 데 쓰일 키 resave: false, // 세션을 언제나 저장할지 saveUninitialized: false, name: "sessionId", store: sessionStore, cookie: { maxAge: 24 * 60 * 60 * 1000, // 쿠키 유효기간 24시간 }, });
app.js
파일에 정의한 session을 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 29 30
import express from "express"; import path from "path"; import "dotenv/config"; import bodyParser from "body-parser"; import cookieParser from "cookie-parser"; import sessionMiddleware from "./src/config/session.js"; import userRouter from "./src/routes/route_user.js"; const app = express(); const __dirname = path.resolve(); // 앱 세팅 app.set("views", "./src/views"); app.set("view engine", "ejs"); // 미들웨어 app.use("/", express.static(`${__dirname}/src/public`)); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: true })); app.use(cookieParser(process.env.COOKIE_SECRET)); app.use(sessionMiddleware); // router app.use("/user", userRouter); // 3000 포트로 서버 오픈 app.listen(3000, () => { console.log("express server on port 3000"); });
세션과 쿠키를 미들웨어로 등록했으니 자동 로그인 기능과 사용자의 id를 출력하는 페이지를 구현해보겠습니다.
Controller에 로직 추가
POST 방식으로 login을 요청할 때 로그인 성공하면 세션에 isLogined 값을 true로 name 값과 함께 저장합니다.
GET 방식으로 로그인 페이지를 요청하면 세션의 isLogined 값을 확인하고 true라면 name 값을 넘겨줍니다.
session.destroy 메서드를 이용해 session을 삭제하는 logout 기능을 구현합니다.
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import UserStorage from "../models/model_user.js";
const output = {
info: (req, res) => {
res.render("user/info", {
// 저장된 세션으로 로그인 된 상태인지 확인
name: req.session.isLogined ? req.session.name : null,
});
},
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) {
// 로그인 성공 시 세션에 기록
req.session.isLogined = true;
req.session.name = user.name;
return (response = { success: true });
}
return (response = { success: false, msg: "비밀번호가 틀렸습니다." });
}
response = { success: false, msg: "존재하지 않는 아이디입니다." };
} catch (err) {
response = {
success: false,
msg: "로그인을 할 수 없습니다.\n잠시 후 다시 시도해주세요.",
};
} finally {
res.json(response);
}
},
register: async (req, res) => {
let response = {};
try {
const user = await UserStorage.getUserInfo(req.body.id);
if (user) {
return (response = { success: false, msg: "아이디가 존재합니다." });
}
response = await UserStorage.createUser(req.body);
} catch (err) {
// 간단한 에러 처리문 작성
response = {
success: false,
msg: "회원가입을 할 수 없습니다.\n 잠시 후 다시 시도해주세요.",
};
} finally {
res.json(response);
}
},
logout: (req, res) => {
// 로그아웃 시 세션 삭제
req.session.destroy((err) => {
if (err) throw err;
// 세션 파괴후 로그인 페이지로 이동
res.redirect("/user/login");
});
},
};
export default { output, process };