부트캠프/[POSCO x Codingon] 웹개발자 풀스택 과정 12기

[POSCO x Codingon] Cookie/Session, 서버 | 웹개발자 풀스택 과정 12기 9주차 회고 1

hyunh404 2024. 4. 23. 22:44
728x90

 

 

9주차 회고

 

 

9주차에는 쿠키와 세션을 이용해 로그인 정보를 저장하고 로그인을 할 수 있는 환경을 만들었으며, 서버를 구축하는 방법에 대해 배울 수 있었다.
http와 express 2가지 방법으로 서버를 구축해봤다.

 

 

 


 

 

1. Cookie

 

: 웹브라우저(클라이언트)에 저장되는 키와 값이 들어있는 작은 데이터 파일

: 이름, 값, 만료일, 경로정보로 구성

 

  • 쿠키 동작 방식

쿠키 동작 방식

 

 

: cookie 모듈을 사용하는지 안하는지에 따라 쿠키가 출력되는 모양이 달라진다.

 

cookie 모듈 사용 x

 

cookie 모듈 사용

 

 

 

  • 'DontReadHttp=myhttp; HttpOnly', ⇒ 콘솔에서는 출력해서 보여주지 않겠다. HttpOnly
  • 'tasty_food=kimchi; Max-Age=6000', ⇒ 만료시간 기록 Max-Age
  • `tasty_food=kimchi; Max-Age=${6000*20}`, ⇒ 백틱을 이용하면 계산값을 넣을 수도 있다.

 


 

 

쿠키의 동작을 이해하기 위해 파이어폭스에서 쿠키를 이용한 불법적으로 로그인하는 실습을 해볼 수 있었다.

 

먼저 구글 크롬에서 mds페이지를 로그인 한 후 개발자 도구의 쿠키값을 복사했다.

다음으로 파이어폭스를 실행해 mds에 들어가준 후,

 

개발자 도구의 쿠키 영역에 복사해온 쿠키값을 추가해주었다.

 

 

그랬더니, 로그인을 하지 않았는데도 로그인이 되어있는 상태로 변했음을 확인할 수 있었다.

 

쿠키를 이용한 불법적인 경로 로그인

 

 


 

 

페이지에서 쿠키를 설정하고 삭제하는 실습도 진행했다.

 

쿠키에 들어갈 내용을 설정 해준 후 cookie-parser모듈을 사용해 구현했다.

const cookieConfig = {
    maxAge: 60*1000,
    httpOnly: true,
    signed: true,
}

app.get('/', (req,res)=>{
    res.render('cookie')
})

// cookie.ejs에서 쿠키 설정하기
app.get('/setCookie', (req,res)=>{
    // 쿠키이름, 쿠키값, 옵션
    res.cookie('myCookie', 'cookiegood', cookieConfig)
    res.send('쿠키 설정 완료')
})

// 쿠키 가져오기
app.get('/getCookie', (req,res)=>{
    console.log('얻어온 쿠키:', req.cookies);
    console.log('얻어온 암호화된 쿠키:', req.signedCookies);
})

// 쿠키 삭제
app.get('/clearCookie', (req,res)=>{
    res.clearCookie('myCookie', 'cookiegood', cookieConfig)
    res.send('clear cookie')
})

 

 

 

이외에도 특별한 경로에서만 쿠키가 설정되도록 쿠키를 정의해줄 수도 있다.

 

다음은 특별한 경로인 /abc에서만 쿠키가 설정되도록 되어있으며, 쿠키를 암호화해서 저장한다.

암호화된 쿠키를 사용하기 위해선 옵션에 signed:true를 추가하고, cookieParser에 임의의 문자열로 시크릿 키를 설정해 구현할 수 있다.

const cookieConfig2 = {
    path: '/abc',
    maxAge: 60*1000,
    httpOnly: true,
    signed: true,
}

app.use(cookieParser("secret key"));

app.get('/', (req,res)=>{
    res.render('cookie')
})

app.get('/setCookie' ,(req,res)=>{
    res.cookie('myCookie','cookiegood',cookieConfig)
    res.send('쿠키설정 완료')
  })
  app.get('/getCookie', (req,res)=>{
    console.log('얻어온 암호화 되지 않은 쿠키 : ',req.cookies)
    console.log('얻어온 암호환된 쿠키 : ',req.signedCookies)
  })

app.get('/abc', (req,res)=>{
    res.cookie('abc-page', 'abc page cookie', cookieConfig2)
    res.render('another')
})

app.get('/clearCookie',(req,res)=>{
    res.clearCookie('myCookie','cookiegood',cookieConfig)
    res.send('clear cookie')
 })

 

 

  • 암호화 안된 쿠키
  1. cookie-parser 사용
  2. app.use(cookieParser())
  3. cookie 설정 res.cookie(이름, 값, 옵션)
  4. cookie 값 확인 req.cookies()
  5. cookie 값 삭제 res.clearCookie(이름, 값, 옵션)

 

  • 암호화된 쿠키
  1. cookie-parser 사용
  2. app.use(cookieParser(임의의 문자열))
  3. 옵션에 signed:true 조건 추가
  4. cookie 설정 res.cookie(이름, 값, 옵션)
  5. cookie 값 확인 req.signedCookies()
  6. cookie 값 삭제 res.clearCookie(이름, 값, 옵션)

 

 

728x90

 

 


 

 

2. Session

 

: 웹서버에 저장되는 쿠키, 사용자 정보를 기억시키고 접속한 시점부터 연결이 끝나는 시점까지 상태 ex.로그인 유지

  • secure : [필수] SID를 생성할 때 사용되는 비밀키로 String or Array 사용 가능.

 

 

 

세션은 express-session모듈을 통해 설정해줄 수 있다.

app.use(session({
    secret: 'mySessionSecret',
    resave: false,
    saveUninitialized: true,
    cookie: {
        httpOnly: true,
        maxAge: 60*1000
    }
}))

app.get('/set', (req,res)=>{
    req.session.name = '홍길동';
    res.send('세션 설정 완료')
})

app.get('/name', (req,res)=>{
    console.log(req.session.name);
    console.log(req.sessionID);
    console.log('req.session', req.session);
    res.send({id: req.sessionID, name: req.session.name})
})

app.get('/destroy',(req,res)=>{
    req.session.destroy(err=>{
        if(err){
            console.log('err');
            res.send('failed')
        }
    })
})

 

 

 

  • Session vs Cookie
Session Cookie
웹서버에 저장 클라이언트에 저장
서버에 요청, 저장, 검증 후에는 검증 절차 없이 자동 요청 허용 쿠키는 삭제 가능, 매번 존재 여부 검사하거나 매번 새로 발행
서버 부하 낮음, 보안 좋음, 속도 빠름 서버 부하 높음, 보안 취약, 속도 느림

 

 


 

 

세션과 axios-post를 이용해서 로그인 유지 화면을 구현하는 실습도 진행했다.

 

로그인 정보를 세션에 먼저 저장해둔 후 로그인 했을 때 로그인 성공, 실패를 구분하고, 페이지를 나갔다가 다시 들어와도 로그인이 유지되어 있도록 만드는 실습이었다.

 

먼저 세션 옵션을 지정하고, 로그인 정보를 정의해줬다.

app.use(session({
    secret: 'secretKey',
    resave: false,
    saveUninitialized: false,
    cookie: {
        httpOnly: true,
        maxAge: 60*1000
    }
}))

const userInfo = { id: 'banana', pw: '1234'};

 

 

 

다음으로 로그인이 유지되어야 하기 때문에 로그인 여부를 판단할 수 있는 조건을 설정해주고, isLogin 값을 설정해 데이터를 보내주는 코드를 작성했다.

app.get('/', (req,res)=>{
    const user = req.session.user;
    console.log('req.sesion.user >', user);
    if(user !== undefined){
        res.render('index', {isLogin: true, user: user})
    } else{
        res.render('index', {isLogin: false})
    }
})

 

 

 

이제 본격적으로 로그인 화면을 구현하고, 로그인 정보가 일치하는지 확인해 로그인 성공 실패를 구분하는 코드를 작성해보겠다.

설정한 로그인 정보인 userInfo와 로그인 페이지로부터 받은 입력 값을 비교해 로그인 성공 실패를 판단해줬다.

app.post('/login', (req,res)=>{
    const { id, pw } = req.body;
    if(id===userInfo.id && pw===userInfo.pw){
        req.session.user=id;
        res.redirect('/')
    } else{
        res.send('로그인 실패')
    }
})

 

 

 

마지막으로 로그아웃을 하면 세션정보가 삭제되도록 코드를 작성했다.

app.get('/logout', (req,res)=>{
    const user = req.session.user;
    if(user!==undefined){
        req.session.destroy(err=>{
            res.redirect('/')
        })
    } else{
        res.send('잘못된 접근입니다.')
    }
})

 

 

 

이렇게해서 완성된 로그인 유지화면은 다음과 같다. 페이지 창을 닫고 다시 들어가도 로그인이 유지됨을 확인할 수 있었다.

 

로그인 유지

 

 


 

 

3. 서버 구축

 

: 서버 - 클라이언트에게 네트워크를 통해 서비스를 제공(프로그램)하는 컴퓨터

: 프로토콜 - 네트워크 환경에서 컴퓨터끼리 정보를 어떠헥 주고받을지 정한 규칙 (통신 규약)

=> ex. http/https, FTP, SSH, SMTP

 

  • 서버 호스팅 : 서버 한대를 통쨰로 임대, 자체적 관리 필요, 작동환경 유동적으로 설정 가능, 가격 비쌈
  • 웹 호스팅 : 서버 한대의 일정 저장공간만 임대해 공유, 가격 저렴, 쉽게 이용 가능, 트래픽/용량 등 사용상 제약 있을 수 있음

 

서버와 클라이언트는 http로 대화한다. ⭐⭐⭐

 

 

: TCP/IP - 컴퓨터가 서로 통신하는 경우, 특정 규칙이나 프로토콜을 사용하여 순서대로 데이터를 전송 및 수신할 수 있다. (통신 규약)

: DNS - 가상 주소를 실제 주소로 매칭 시키는 역할 수행, 도메인 주소 → IP 주소

 

 

서버를 구축하는 방법 : http, express

 

  • http.createServer().listen()
const http = require('http');
http.createServer(function(req,res){
   if( req.headers.cookie !== undefined){
    console.log('이미 쿠기를 갖고 있나요 ',req.headers.cookie )
  }
   res.writeHead(200, {
       'set-cookie':['my_cookie=choco', 'your_cookie=strawberry']
   })
   res.end('Cookie')
}).listen(3000, ()=>{
  console.log('3000 server is running')
})

 

 

  • express - listen
const express = require('express');
const app = express();
 
app.listen(8000, ()=>{
    console.log('8000 server is running...');
})

 

 


 

 

쿠키와 세션을 이용해 로그인하는 방법을 파악하고 직접 로그인을 유지할 수 있는 코드를 작성해보면서 쿠키, 세션이 작동하는 구조를 이해할 수 있었다.

로그인 유지를 구현하는 실습에서는 로그인하는 것까지는 어렵지 않았으나 역시 유지를 구현하는 과정에서 쉽지 않았다.
고민하면서 찾아낸 문제점은 로그인 여부를 판단하는 코드를 작성하지 않았던 것이었다.

그러나 로그인 여부를 판단하는 과정을 어떤 방식으로 작성해야할지 모르겠어서 리더님의 풀이를 보고 다시한번 구현을 시도해 성공할 수 있었다.
로그인 여부를 데이터로 전송해 판단하고, 그 결과에 맞게 페이지 렌더링을 구분해서 진행되도록 코드를 작성했다.
실제로 isLogin이라는 임의의 이름을 사용해서 로그인 true, false 값을 전달해 구분지을 수 있었다.

역시 아직까지는 혼자서 조건을 만족하는 설정을 구현하고 동작을 만들어 내는 것이 쉽지 않다고 느꼈고, 더 노력해서 만들고 싶은 동작과 기능을 구현해낼 수 있는 개발자가 되고 싶다고 생각했다.
728x90