1. 서버와 서블릿 가동
서버가 가동될 때 서블릿 객체가 일반 메모리 영역에 하나 생성
이 서블릿 객체는 상속되는 모든 데이터도 함께 생성하며, application scope에 속함
서버 가동 시 객체가 하나 생성되고, 이는 param 테이블과 attribute 테이블 등의 정보를 포함
2. 사용자 요청 처리
사용자가 웹 서버에 index.html을 요청하고 로그인 정보를 입력하여 request를 보낼 시
최초 request는 쿠키가 없고 POST 방식으로 id와 pw가 전송되어 서블릿에 도착
요청은 request queue에 쌓이고 request 객체가 생성(각 객체는 동일한 우선순위를 가짐)
3. 스택과 스레드 처리
작업이 시작되면 메모리의 스택 영역의 메인 스택에 request와 response 객체의 주소가 가리켜짐
스레드는 스택 영역 내에서 작업을 수행하며, 다른 스레드가 CPU 사용 권한을 소모하면 대기 상태로 넘어감
이 과정은 반복되며 여러 스레드가 순차적으로 작업을 수행
4. DB 확인 및 세션 생성
request 정보는 DB에 가서 확인 작업을 수행
확인이 완료되면 user 객체가 생성, 이 객체는 회원 정보를 포함
세션을 사용하여 이 객체를 저장
5. 세션 관리
req.session을 통해 세션이 할당, 세션은 테이블 형태로 값을 저장
쿠키가 생성되고, response 헤더에 포함되어 응답
커넥션이 종료되어 스택영역이 삭제된 후 쿠키가 삭제되어도 세션에 남아있는 user 정보는 세션 유지 시간(기본 30분) 동안 유지
express-session
express-session은 서버가 세션을 이용하게 해 주고 사용자 쿠키에 세션 정보를 담을 수 있게 하는 미들웨어
사용자 쿠키에 세션 데이터를 담을 때는 세션의 모든 데이터를 담는 것이 아니라 세션의 id값을 저장하고 서버에서 데이터를 관리하게 함
express-session 미들웨어를 사용하는 형태
let session = require('express-session');
app.use(session({
secret : '암호키', //세션 아이디를 암호화하기 위한 재료 값
resave : false, //세션을 접속할 때마다 새로운 세션 식별자(sid)의 발급 여부를 결정
//일반적으로는 false로 설정
saveUninitialized : false
}));
세션이 생성되었지만 어떠한 데이터도 추가되거나 변경되지 않은 상태를 uninitialized라고 함
saveUninitialized : true
saveUninitialized : false
saveUninitialized : true로 설정하면 개발자 도구에서 세션ID(SID)를 삭제해도 새로고침할 때마다 새로운 세션이 생성되어 서버 메모리를 많이 차지해 과부하 되는 문제 발생이를 방지하기 위해
saveUninitialized : false로 설정하여 필요하지 않은 세션이 서버에 저장되지 않도록 함
모든 요청에 대해 서버 측 렌더링(SSR)을 수행하면 서버에 과부하가 발생할 수 있음, 이를 해결하기 위해 CSR을 사용
CSR을 사용하기 위해서는 서버에서 전달받은 데이터로 클라이언트에서 페이지를 렌더링하는데, 이 과정에서 세션 정보를 이용
sid(session ID)
일반적으로 세션을 관리하기 위해 사용
sid는 서버에서 생성되어 클라이언트의 쿠키에 저장되고, 이후 요청 시 이 쿠키를 통해 세션을 식별
uid(user ID)
사용자 식별을 위한 ID, 보안 쿠키(httpOnly)로 설정됨
httpOnly로 설정된 쿠키는 클라이언트 측에서 바닐라 JavaScript로 접근할 수 없음
uid 쿠키를 httpOnly 속성 없이 설정하여 클라이언트 측에서 uid를 이용해 사용자 정보를 처리하게 해 CSR 수행
app.get('/login', function (req, res) {
if (req.session.user) { //req.session.user에 사용자의 세션이 이미 등록되어 있다면
res.render('index.ejs', { user: req.session.user }); //홈 화면인 index.ejs에 {user:req.session.user} 데이터를 넘겨주며 이동
} else {
res.render('login.ejs');
}
});
app.post('/login', function (req, res) {
console.log("아이디 : " + req.body.userid);
console.log("비밀번호 : " + req.body.userpw);
mydb
.collection('account')
.findOne({ userid: req.body.userid })
.then(result => {
if (result != null && result.userpw == req.body.userpw) {
req.session.user = req.body;
console.log('새로운 로그인');
res.render('index.ejs', { user: req.session.user });//처음 로그인 시에 로그인에 성공하면
//홈 화면인 index.ejs로 {user:req.session.user} 데이터를 넘겨주며 이동
} else {
res.render('login.ejs', { user: null }); //로그인에 실패했다면 login.ejs로 이동
}
});
});
app.get('/logout', (req, res) => {
console.log('로그아웃');
req.session.destroy(); //req.session.destroy() 함수를 호출하면 현재 도메인의 세션을 삭제
res.render('index.ejs', { user: null });
});
app.get('/signup', (req, res) => {
res.render('signup.ejs')
});
app.post('/signup', (req, res) => {
console.log(req.body);
console.log(req.body.userpw);
mydb.collection('account')
.insertOne({
userid: req.body.userid,
userpw: req.body.userpw,
usergroup: req.body.usergroup,
useremail: req.body.useremail
})
.then(result => {
console.log('회원가입 성공');
})
.catch(err => {
console.log(err);
});
res.redirect('/');
});


평문(plain text)을 암호문(crypto text)으로 변환하는 과정
사용자가 입력한 데이터를 알아볼 수 없는 데이터로 변경하여 외부로부터 데이터를 보호
암호화를 했다면 암호문을 다시 평문으로 변환할 수 있어야 하는데 이러한 과정을 복호화라고 함
밑의 코드들에서는 단방향 암호화 기법인 SHA256을 이용
npm install sha256
const sha = require('sha256');
app.post('/signup', (req, res) => {
console.log(req.body);
console.log(sha(req.body.userpw));
mydb.collection('account')
.insertOne({
userid: req.body.userid,
userpw: sha(req.body.userpw),
usergroup: req.body.usergroup,
useremail: req.body.useremail
})
.then(result => {
console.log('회원가입 성공');
})
.catch(err => {
console.log(err);
});
res.redirect('/');
});

이미 암호화된 DB의 비밀번호를 복호화할 수 없기에 반대로 사용자가 입력한 비밀번호를 암호화하여 비교한 후 로그인
app.post('/login', function (req, res) {
console.log("아이디 : " + req.body.userid);
console.log("비밀번호 : " + req.body.userpw);
mydb
.collection('account')
.findOne({ userid: req.body.userid })
.then(result => {
if (result != null && result.userpw == sha(req.body.userpw)) {
req.session.user = req.body;
console.log('새로운 로그인');
res.render('index.ejs', { user: req.session.user });
} else {
res.render('login.ejs');
}
});
});
https://rattle-coal-060.notion.site/f7bc264fa0b84632b0033645237fc102 내용 추가하기