DEVELOP
article thumbnail

Session의 개념 

- coockie의 문제점  

 : 보안이 취약 

# Session 

 : 사용자 정보를 저장하는 또 다른 방법  

- 클라이언트의 컴퓨터에는 오직 사용자의 식별자인 id값만을 저장 

- 실제 데이터는 서버의 DB, 메모리 등에  저장 

- 서버에 식별자를 전송하면 실제 데이터를 읽어옴 

- 보안에 취약한 쿠키를 보완해주는 역할 

- 구체적인 값을 저장하는 대신에 고유한 값을 전달

- connect.sid 값을 서버에 전달 

- connect.sid  값이 같은 요청들은 같은 사용자의 접근이라고 간주함 

- connect.sid 값으로 요청이 들어오면 서버에서 그 요청에 해당하는 count 값을 가져와서 1을 가져와 브라우저에 응답 

- 쿠키 값이 사용자의 컴퓨터에 저장되는 것이 아니기 때문에 덜 위험


session 사용하기

 

- session 설치 (터미널에)

npm install express-session --save

- session 사용법 

const express = require('express');
const session = require('express-session');
const app = express();

app.use(session({
  secret: '1234%^&123$%^sff',
  resave: false,
  saveUninitialized: true, // session의 id를 session을 실제 사용 전까지 발급x 
}));
 

express-session

Simple session middleware for Express. Latest version: 1.17.3, last published: 7 months ago. Start using express-session in your project by running `npm i express-session`. There are 4460 other projects in the npm registry using express-session.

www.npmjs.com


session.count 값 확인하기

- localhost:3003/count 접속할 때 마다 count 값이 증가한다는 것을 localhost:3003/tmp 에 접속해 확인
const express = require('express');
const session = require('express-session');
const app = express();

app.use(session({
  secret: '1234%^&123$%^sff',
  resave: false,
  saveUninitialized: true, // session의 id를 session을 실제 사용 전까지 발급x 
}));

app.get('/count', (req, res) => {
  if(req.session.count){
    req.session.count++;
  }else{
    req.session.count = 1;
  }
  res.send("hi session");
});

app.get('/tmp',(req,res)=>{
  res.send('count : '+req.session.count);
})

app.listen(3003, () => {
  console.log('Connected 3003 port!!');
});

- count 라는 이름으로 저장되지 않고, connect.sid 값으로 저장되는 것을 확인

- connect.sid의 value를 session에 저장하고, 그 값에 따라 데이터를 서버에 저장해서 유지할 수 있다. 

- express-session은 메모리에 데이터를 저장하므로, 애플리케이션 종료 시 해당 메모리가 초기화 됨

- 실제 서비스 개발 시 데이터를 DB에 저장해야 함 


Session으로 로그인하기

- /auth/login 에서 username / password 입력 후 submit 하면 post 방식으로 보내짐

- user의 정보는 아래와 같이 임시 설정,  if문으로 비교  (DB로 관리가 원칙임)

var user = {
    username : 'egoing',
    password : '111',
    displayName:'Egoing'
  };

- post 방식으로 /auth/login 접속 시 user, password 가 동일하면, /welcome 으로 이동

- 동일하지 않으면' Who are You? '출력 후 login으로 다시 이동하도록 링크 생성 

-  /welcome 에서는 'Hello, (displayName)' 이 출력되고 logout 링크 생성 

- logout 링크 클릭 시 /welcome 에서 'Welcome' 을 출력하고, login 링크 생성, login 링크 클릭 시 /auth/login 으로 redirect

 

로그인 성공 / 실패

const express = require('express');
const session = require('express-session');
const bodyParser = require('body-parser');

const app = express();
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
  secret: '1234%^&123$%^sff',
  resave: false,
  saveUninitialized: true, // session의 id를 session을 실제 사용 전까지 발급x 
}));

app.get('/auth/logout',(req,res)=>{
  delete req.session.displayName;
  res.redirect('/welcome');
})
app.get('/welcome',(req,res)=>{
  if(req.session.displayName){
    res.send(`
    <h1>Hello,${req.session.displayName}</h1>
    <a href="/auth/logout">logout</a> 
    `);  
}else{
  res.send(`
    <h1>Welcome</h1>
    <a href="/auth/login">login</a> 
    `);  
}});

app.post('/auth/login',(req,res)=>{
  var user = {
    username : 'egoing',
    password : '111',
    displayName:'Egoing'
  };
  var uname = req.body.username;
  var pw = req.body.password;
  if(uname===user.username&&pw===user.password){
    req.session.displayName = user.displayName;
    res.redirect('/welcome');
  }else{
    res.send(`Who are you?<a href = "/auth/login">login</a>`);
  }
});

app.get('/auth/login',(req,res)=>{
  var output= `
  <h1>Login</h1>
  <form action="/auth/login" method = "post">
  <p>
    <input type ="text" name = "username" placeholder = "username"></input>
  </p>
  <p>
    <input type ="password" name = "password" placeholder = "password"></input>
  </p>
  <p>
    <input type = "submit"></input>
  </p>
  </form>`;

  res.send(output);
});

app.listen(3003, () => {
  console.log('Connected 3003 port!!');
});

- get 방식과 post 방식 참고글 

 

[네트워크] get 과 post 의 차이

GET 과 POST 는 HTTP 메서드로 클라이언트에서 서버로 무언가를 요청할 때 사용한다. 2019/06/01 - [IT 정보 로그캣/CS] - [네트워크] http 란 [네트워크] http 란 기본적으로 네트워크 통신을 할 때 처음 접하

noahlogs.tistory.com

- post 방식으로 데이터 전송 시 필요한 모듈 : body-parser

 

body-parser

Node.js body parsing middleware. Latest version: 1.20.1, last published: 2 months ago. Start using body-parser in your project by running `npm i body-parser`. There are 21900 other projects in the npm registry using body-parser.

www.npmjs.com


file을 data store로 사용하기

- file에 data를 저장하기 위한 모듈 :session-file-store

 

session-file-store

Session file store is a provision for storing session data in the session file. Latest version: 1.5.0, last published: 2 years ago. Start using session-file-store in your project by running `npm i session-file-store`. There are 158 other projects in the np

www.npmjs.com

- session-file-store 설치 방법 

npm install session-file-store --save

-  사용법 

   : FileStore를 정의하고 app.use(session) 에 store 로 FileStore() 지정 

const FileStore = require('session-file-store')(session); //의존관계 

app.use(session({
  secret: '1234%^&123$%^sff',
  resave: false,
  saveUninitialized: true, 
  store:new FileStore(),
}));

{"cookie":{"originalMaxAge":null,"expires":null,"httpOnly":true,"path":"/"},"__lastAccess":1669615818781,"displayName":"Egoing"}

- session 디렉토리가 생성되고 쿠키 값이 json 파일에 저장됨

- 로그인 성공 시 displayName 값 저장됨 


 

mysql 연동하기

- mysql에 data를 저장하기 위한 모듈 :express-mysql-session

 

express-mysql-session

A MySQL session store for express.js. Latest version: 2.1.8, last published: 7 months ago. Start using express-mysql-session in your project by running `npm i express-mysql-session`. There are 41 other projects in the npm registry using express-mysql-sessi

www.npmjs.com

- express-mysql-session 모듈 설치 

npm install express-mysql-session --save

- express-mysql-session  사용법

var mysqlStore = require('express-mysql-session')(session);

var options = {
  host: 'localhost',
  port: 3306,
  user: 'root',
  password: '비밀번호',
  database: 'session_login'
};
app.use(bodyParser.urlencoded({ extended: false }));
app.use(session({
  secret: '1234%^&123$%^sff',
  resave: false,
  saveUninitialized: true,
  store: new mysqlStore(options),
}));

- 연동이 성공했다면 해당 데이터베이스에 sessions 테이블이 자동 생성된다.

- /auth/login 접속 시 튜플이 생성되고, 로그인에 성공할 시 해당 튜플의 data 값에 displayName 값이 추가된다.


req.session.save 

- redirect 시 문제점 

- javascript의 비동기적 실행 때문에 데이터가 변화 되기 전 redirect 되어 제대로 작동되지 않는 경우가 있음, 

#req.session.save() 

 : 데이터의 변화가 저장이 끝났을 때 인자의 함수가 실행됨 

 - redirect할 때에 의미 있음 

// 기존 
 
 delete req.session.displayName;
 res.redirect('/welcome');
 
// 수정
 req.session.displayName = user.displayName;
 req.session.save(()=>{
    res.redirect('/welcome');
 });

 

profile

DEVELOP

@JUNGY00N