WEB – 세션(Session)의 개념과 활용

본 포스팅은 WEB – 쿠키(Cookie)의 개념과 활용과 이어집니다!

쿠키의 보안 이슈를 해결하기 위해 나온 것이 세션입니다.

쿠키는 사용자가 입력한 값이 웹 브라우저에 그대로 노출된다는 점에서 보안 상으로 취약합니다.

세션을 이용하면 사용자가 입력한 값은 웹 브라우저에 고유한 식별자로만 볼 수 있고, 실질적인 데이터는 서버에 식별자 파일로 저장됩니다.

웹 브라우저에서 보이는 세션의 값은 세션ID라고 불리고 클라이언트마다 다릅니다.
따라서 요청한 클라이언트의 수만큼 식별자 파일이 생겨납니다.
(웹 브라우저 종료 후 다시 접속 시 새 클라이언트로 인식)

또한 쿠키와 달리 처음에만 (서버->클라이언트)로 전달되고 이후에는 (클라이언트->서버)로만 전달됩니다.
그래서 두 번째 이상 접속부터 ‘요청 쿠키’만 확인할 수 있습니다.

처음에 클라이언트로 전달되는 세션의 값은 위같이 식별자에 불과하며
이후로 서버에 전달되는 세션도 식별자 파일을 탐색하는 용도에 불과합니다.

즉 쿠키처럼 서버가 보내는 중요 정보를 웹 브라우저에 남기는 일은 없을 것입니다!

따라서 해킹의 위험을 줄일 수 있는 (인증, 개인화, 방문자의 상태 체크) 방법이라고 생각할 수 있습니다.
현대 어플리케이션에서 쿠키는 사용자를 식별하는 용도로만 사용됩니다.

쿠키: 웹 브라우저에 정보(value)를 남겨 놓은 채 (인증, 개인화, 방문자의 상태 체크)를 하는 방법
세션: 웹 서버에만 정보(value)를 남기면서 안전하게 (인증, 개인화, 방문자의 상태 체크)를 하는 방법


JavaScript로 세션을 만들어보도록 하겠습니다.

npm install express-session
var express = require('express')
var parseurl = require('parseurl')
var session = require('express-session')

var app = express()

// 세션 미들웨어 : request객체의 멤버로 세션이라는 객체를 추가 (중괄호에 적힌 내용을 기반으로 객체 생성 )
app.use(session({
  secret: 'asadlfkj!@#!@#dfgasdg', // 세션 데이터를 얻기 위해 필요한 멤버, 변수로 처리해야 보안 효과를 봄
  resave: false, // 세션 데이터라는 것이 바뀌기 전까지는 세션 저장소의 값을 저장하지 않는다. (false로 하면 좋음)
  saveUninitialized: true // 세션이 필요하기 전까지는 세션을 구동하지 않는다. (true로 하면 좋음)
}))

app.get('/', function (req, res, next) {
    console.log(req.session); // 멤버로 추가된 세션 객체 확인
    if(req.session.num === undefined){
        req.session.num = 1; // 세션 객체에 num프로퍼티 추가
    } else {
        req.session.num =  req.session.num + 1; // 세션 객체에 num프로퍼티 업데이트
    }
    res.send(`Views : ${req.session.num}`);
})

app.listen(2000, function(){
    console.log('2000!');
});

위는 Express 프레임워크를 이용해서 웹 서버를 만들고
서버 프로그램 내부에 세션 객체를 생성한 다음 라우팅을 하는 소스입니다.

세션 미들웨어는 주석을 참조해서 제작하면 됩니다.

이 세션 미들웨어가 실행되면 request.session속성이 생성됩니다.
해당 속성은 사용자가 작성한 secret,resave,saveUninitialized를 멤버로 가지는 객체입니다.

객체(request.session)를 앞으로 세션 객체라고 하겠습니다.

사용자가 루트 페이지에 처음 접속하면 세션 객체에 num 속성이 없기 때문에 undefined가 돼서 값이 1인 num속성을 추가하게 됩니다.

이후 접속을 하면 num속성이 업데이트되고 변경된 num값이 화면에 출력됩니다.

즉 위 소스의 기능은 ‘세션 객체 데이터를 이용한 방문 수 확인’입니다!


세션 저장소 (Session Store)

세션 작업을 하면서 얻은 데이터(세션 객체 멤버)를 저장하는 공간, default로 서버의 메모리에 저장됨 (휘발성)
-> 서버를 종료하면 서버 프로그램 관련 내용이 메모리에서 지워지면서 세션 작업 데이터가 다 없어짐

세션 저장소는 기본적으로 휘발성이기 때문에 비휘발성 세션 저장소를 이용할 필요가 있습니다!

그렇게 하기 위한 작업 방법은 아래와 같습니다.

1. npm install session-file-store로 새로운 패키지를 설치
2. 세션 미들웨어에서 store멤버의 값을 FileStore 객체로 초기화

npm install session-file-store
var FileStore = require('session-file-store')(session) // 생성자 함수를 반환

var app = express()

// 세션 미들웨어 : request객체의 프로퍼티로 세션이라는 객체를 추가 (중괄호에 적힌 내용을 기반으로 객체 생성 )
app.use(session({
  secret: 'asadlfkj!@#!@#dfgasdg', // 세션 데이터를 얻기 위해 필요한 멤버, 변수로 처리해야 보안 효과를 봄
  resave: false, // 세션 데이터라는 것이 바뀌기 전까지는 세션 저장소의 값을 저장하지 않는다. (false로 하면 좋음)
  saveUninitialized: true, // 세션이 필요하기 전까지는 세션을 구동하지 않는다. (true로 하면 좋음)
  store:new FileStore() // FileStore객체 생성 후 store멤버에 저장 -> 세션 저장소를 sessions디렉토리 내부에 위치시킴
}))

위 작업을 마치고 다시 웹 서버에 접속하면 Session디렉토리에 다음과 같은 파일이 생성됩니다.

이 파일이 바로 식별자 파일이며 동시에 세션 저장소입니다.

세션 ID가 ‘BvBbGV~’인 클라이언트의 세션 데이터는 모두 이 곳에 저장됩니다.

num키는 해당 클라이언트의 접속으로부터 생성된 ‘세션 객체 데이터(멤버)’입니다.
lastAccess키는 가장 최근에 접속한 시간으로 별도 작업을 하지 않아도 알아서 저장됩니다.

이 파일은 주로 ‘세션 파일’이라고 부릅니다!

P.s. passport인증을 할 때는 세션 파일이 핵심적인 역할을 합니다. 세션 파일 안에 있는 중요한 데이터 (ex)로그인한 사용자 ID)를 기반으로 모든 미들웨어가 동작합니다.


세션 데이터 저장

JavaScript의 비동기성에 의해 세션 데이터를 저장하기 전에 그 다음 코드가 실행되는 경우도 있습니다. (대표적: 리다이렉션) 이를 극복하기 위해 save라는 메소드를 이용합니다.

request.session.num=1;
response.redirect('/');

세션 객체(request.session)에 num속성을 등록한 순간부터 세션 저장소(세션 파일)에 num키와 값이 저장돼야 하지만
오류가 걸릴 수 있습니다.

그 대표적인 경우가 리다이렉션을 해서 다음 라우트로 넘어가는 순간입니다.

자세히는 모르겠지만 비동기성 성질이 원인이라는 의견이 많습니다.

해결법은 다음과 같이 save메소드를 이용하는 것입니다.

해당 메소드는 비동기 함수로 세션 데이터를 저장한 뒤에야 콜백을 호출합니다.

request.session.num=1;
request.session.save(()=>{ response.redirect('/'); });


쿠키와 인증 방법 비교하기

쿠키의 활용 (인증)
로그인 창에서 클라이언트가 올바른 ID, PW를 입력하면 서버 측에서 ID와 PW쿠키를 생성하고 전송합니다.
이렇게 생성된 쿠키는 통신하면서 서버로 다시 전달됩니다. (이중 확인)
만약 쿠키가 서버로 전달되면 로그인 됐다고 판단하고 권한이 있는 컨텐츠를 전달합니다.
-> 쿠키 그 자체가 인증에 쓰임

세션의 활용 (인증)
로그인 창에서 클라이언트가 올바른 ID, PW를 입력하면 서버 측에서 인증됐다는 세션 객체 멤버(request.session.is_logined)를 생성하고 true로 초기화합니다. 앞으로 이 세션 데이터가 true이면 권한이 있는 컨텐츠를 전달합니다.
-> 세션 객체가 인증에 중요하게 쓰임


세션의 인증 심화

Passport.js
페이지에서 안전하게 로그인하기 위한 프레임워크 [ SNS 계정과 연동도 가능 ]
(패스포트 코드는 세션을 활용하기 때문에 세션 코드 밑에 존재해야 됩니다.)

Passport 패키지
npm install passport
npm install passport-local

인증 절차
1.
authenticate함수의 첫 번째 인수로 로그인 처리 방식을 확인합니다. (로컬 방식, SNS연동 방식)
2. Strategy를 이용해서 user 정보와 일치하는지 비교합니다.
3. serializeuser를 통해 세션 파일의 passport 키에 user를 저장합니다. (로그인 성공 사실 저장)
4. deserializeuser를 통해 request.user 객체에 유저 정보를 저장합니다. (다른 라우트에서 사용하기 쉽게 만듦)
5. authenticate의 콜백함수를 실행합니다.
6. request.user가 존재하면 권한이 있는 컨텐츠를 전달합니다.

자세한 내용은 passport.org를 참조하시기 바랍니다!!


읽어주셔서 감사합니다!

Node에 관한 게시물은 CodeIt,생활코딩의 강의 내용을 정리한 글입니다. 강의 이미지나 내용 자체를 업로드하지는 않습니다!!

Leave a Reply

Your email address will not be published. Required fields are marked *