세션 기반 인증 방식
이 사용됨용어 정리
세션 : 서버와 클라이언트의 연결이 활성화된 상태
세션 ID : 웹 서버 또는 DB에 저장되는 클라이언트에 대한 유니크 ID
1. 로그인 요청(Login Request)
- 클라이언트 : 사용자가 로그인 페이지에서 사용자명과 비밀번호를 입력하고
이를 포함한 POST 요청을 서버로 전송
POST /login
username=david
password=davidh
2. 서버 인증(Server Authentication)
- 서버 : 사용자가 보낸 자격 증명을 확인
데이터베이스를 참조하여 사용자명과 비밀번호가 일치하는지 검증
- 인증 성공 시 :
1. 세션 ID를 생성
2. 생성된 세션 ID를 쿠키에 담아 클라이언트로 반환
3. 세션 ID와 관련된 세션 데이터를 DB에 저장
3. 세션 ID 설정(Set Session ID)
- 서버 : 생성된 세션 ID를 클라이언트로 전송
이때, HTTP 응답 헤더에 Set-Cookie를 사용하여 세션 ID를
클라이언트의 쿠키에 저장하도록 지시
Set-Cookie: SESSIONID=86C530ACAF44D1B05588019ECBC0C737C
4. 클라이언트의 세션 ID 저장(Cient Stores Session ID)
- 클라이언트 : 클라이언트 브라우저는 서버로부터 받은 세션 ID를 쿠키에 저장
5. 인증된 요청 처리(Handling Authenticated Requests)
- 클라이언트 : 사용자가 인증된 상태에서 서버에 요청을 보낼 때마다,
브라우저는 자동으로 쿠키에 저장된 세션 ID를 포함하여 서버로 전송
Cookie: SESSIONID=86C530ACAF44D1B05588019ECBC0C737C
6. 세션 검증(Session Validation)
- 서버 : 요청에 포함된 세션 ID를 확인
1. 세션 ID가 데이터베이스에 저장된 세션 데이터와 일치하는지 확인
2. 세션이 유효한지(예: 만료되지 않았는지) 검증
- 유효한 세션일 경우 : 요청을 처리하고, 해당 사용자의 데이터를 반환
7. 컨텐츠 제공(Providing Content)
- 서버 : 세션 검증이 완료되면, 요청된 컨텐츠를 클라이언트로 전송
npm install escape-html express express-session
// 사용자가 보낸 값을 보안을 위해 escape하기 위한 모듈입니다. // 예를 들어 foo & bar >> foo & bar 로 바꿉니다.
const escapeHtml = require("escape-html");
const express = require("express");
const session = require("express-session");
const app = express();
// 9e8821c8ef4ab43ba09310af54e98caedc13e314efdea720bf513b9b3675faf4
app.use(
session({
name: "session-id",
secret: "9e8821c8ef4ab43ba09310af54e98caedc13e314efdea720bf513b9b3675faf4",
resave: false,
saveUninitialized: false,
})
);
// 미들웨어 : auth
const isAuthenticated = (req, res, next) => {
// 만약 세션이 있다면 다음 미들웨어로. 그게 아니라면. 다음 route로 제어권을 넘깁니다.
if (req.session.user) next();
else next("route");
};
// 만약 isAuthenticated 하다면 logout을 보여준다.
app.get("/", isAuthenticated, function (req, res) {
res.send(escapeHtml(req.session.user) + "님 환영합니다!");
});
// 만약 isAuthenticated 하지 않다면 login을 보여준다.
app.get("/", function (req, res) {
res.send(
'<p>로그인</p><form action="/login" method="post">' +
'Username: <input name="user"><br>' +
'Password: <input name="pass" type="password"><br>' +
'<input type="submit" text="Login"></form>'
);
});
// 로그인요청 >> 세션 생성
app.post(
"/login",
express.urlencoded({ extended: false }),
function (req, res) {
if (req.body.user === "leesfact" && req.body.pass === "1234") {
req.session.regenerate(function (err) {
if (err) next(err);
// input : user 에 있는 값을 req.session.user에 할당
req.session.user = req.body.user;
// 세션 생성 >> 쿠키값 설정 >> 이후 다시 리다이렉팅
req.session.save(function (err) {
if (err) return next(err);
res.redirect("/");
});
});
} else res.redirect("/");
}
);
app.listen(3000, () => console.log("server is started :http://localhost:3000"));