09/10, Shortly.express

Ian·2020년 9월 10일
0

Today I Learned

목록 보기
23/40
post-thumbnail

Office Hour


대성님이 추천해주신 문건 → "인터넷사이트 쿠키의 주요 이슈 및 취약점 분석"

express-session 을 통해 세션 객체에 어떤 값을 저장하는 법

req.session.username = 'username'

이런 식으로 session 객체에 key-value 형식으로 저장할 수 있다. 그 외에도 shortly.express 를 해결하기 위해선 express 기반으로 인증을 구현하기 때문에

암호학에서, SALT 란?

암호화 하려는 값에 별도의 값을 추가해서, 암호화를 조금 더 복잡하게 하는 과정을 의미한다. 도식으로 그려보면 이렇다. 해시라는 과정은 "으깬다" 라는 것이고, 그렇게 내 데이터를 "으깨는" 과정을 digest 라고 한다.

endcoding, decoding

"현실적으로" 안 된다. 물론, 천문학적인 시간 끝에는 가능하다. 그러나, 사람들이 자주 사용하는 암호라면 이미 만들어보는 rainbow table 이라는 "주로 사용하는 암호들" 을 여러가지 암호방식에 따라 해싱한 값들을 모아놓은 값들로부터 슥 찾아보고, 일치하는게 있으면 그런 천문학적인 시간이 걸리지 않아도 뚫려버린다.

더 나은 보안을 위해

  • 사용자 : unique 한 비밀번호를 사용해야 한다. 1q2w3e4r 같은 비밀번호가 아니라!
  • 서비스 제공자 : salt 를 랜덤하게 붙여놓든가, 해싱을 여러 번 한다든가 해서 decoding 하기가 어렵게 하면 된다. salt 를 어디에 무엇으로 넣었는지, 해싱을 몇 번이나 했는지만 유출되지 않으면 풀 수 없다.

그리고 공개키 알고리즘이라고 해서 절대로 보안성이 낮은 게 아니다. 오히려 내가 임의로 구현한 암호화 알고리즘보다 "훨씬" 낫다.

token, session 에 대해서

서버에서 토큰을 저장하고 관리한다?

정확히 말하면 "토큰을 가지고", "세션 객체" 에 접근하는 것이다. 토큰을 저장하고 세션 객체에 접근하는 건 클라이언트이고, 서버는 토큰을 저장하는게 아니라, 토큰에 모종의 가공 과정을 거쳐 세션 객체에 접근하여 정합성을 판단하는 역할을 한다.

서버는 유저의 요청에 담긴 토큰이 유효한지, 유저가 현재 브라우저에 접속 중인지 여부 등을 확인한다?

"확인한다" 라기보다는, 굳이 확인할 수는 있지만 반드시 확인을 하는 건 아니다. 그렇기 때문에 오답.

질문들

세션도 만료시간이 있다던데 세션은 계속 존재하는 건가요??

서버개발자의 판단에 따라 달라진다. 그리고, 세션을 보관하는데 기한을 설정하는 경우가 일반적이다. 사용자의 경우는 내가 로그아웃을 안 했는데 누가 내 계정을 사용하는 상황을 방지할 수 있어서 좋고, 서버측에서는 계~속 토큰이 쌓이는 과정에서 생기는 부하의 증가를 막을 수 있어서 좋다.

세션ID가 일정한 거랑 수시로 변경하는게 웹 상에서 보이던데 현재 하고 있는 코드에서는 일정한거로만 비춰졌어요. 실질적으로 수시로 변경 작업을 하는건가요 ?

수시로 변경을 하기도 하고, salt 등을 넣어서 unique 한 암호를 만들기도 한다.


Shortly.express

sequelize 의 hooks API

Sequelize

afterValidate 라는 hooks API 의 메서드는 React 의 Life Cycle 메서드와 비슷하다. 이 경우를 풀어서 설명하자면, hooks 를 걸어 validation 이 끝난 이후, afterValidate 에 할당된 함수를 실행한다는 의미이다.

그리고 우리가 진행할 스프린트의 afterValidate 코드는 crypto 모듈을 이용하여 urlsurl 에, 특정한 salt 를 넣고, 그것들을 해싱하고, 만든 결과물의 일부를 slice 를 통해 잘라준 뒤, urlscode column 에 해당 hashed value 를 넣어주는 과정을 의미한다는 것을 알게 되었다.

user 의 로그인 / 회원가입 / 정보조회 / 로그아웃 기능 구현하기

모든 기능 구현 전에 앞서 공통적으로 해야하는 사항들

  1. 특정한 endpoint 로 날아오는 GET, 혹은 POST 요청을 handling 할 수 있어야 한다.
    1. get
    2. post
  2. 해당 요청들을 통해...
    1. 요청에 대한 기본적인 응답 (예를 들면, 정보조회는 table 로부터 정보를 조회할 수 있게 쿼리문을 처리해주는 과정 등이 있을 것임)
    2. 유저 정보와 cookie, session 에 관련된 만큼, setHeader 등의 메서드를 이용하여 cookie, session, token 발급을 해 주어야 한다.
    3. 그렇게 발급한 것들을 서버에서 정합성을 판단해야 하며, 유출되지 않게끔 암호화를 해 주어야 한다.

회원가입 기능구현

  1. 특정한 endpoint 로 날아오는 사항들 핸들링하기 : POST 요청이 /user/signup 으로 발송이 된다.
  2. 발송하는 request 는 이러한 구조이다.
{
	email: 'test@gmail.com',
	username: 'testuser',
	password: 'asdfasdf'
}
  1. 이제 해당 데이터들을 res.body 로 받고, 각 항목을 users 라는 table 에 INSERT INTO 로 생성해준다.

  2. 해당 생성 결과물들을 res.body 에 담아서 보내주어야 한다.

  3. DB에서 해당 값을 추가하려 했을 때 이미 존재하는 계정의 경우 "already exist user" 라는 메시지를 보내고, 별도의 DB 생성은 하지 않고 response 를 날린다.

Sequelize

여기서 5번의 경우는 여러번 쿼리를 부르는 방식으로 조건문을 통해 처리해주지 않고, findOrCreate API 를 사용해서 간단하게 처리하고자 한다.

users.findOrCreate({
      where: { email: userData.email },
      defaults: {
        email: userData.email,
        username: userData.username,
        password: userData.password
      }
    }).then(
      (value) => {
        let justAddedUser = value[0].dataValues;
        let isCreated = value[1];
        if (isCreated) {
          res.send(justAddedUser)
        } else {
          res.status(409).send('Already exists user')
        }
      }
    )

로그인 기능구현

  1. 특정한 endpoint 로 날아오는 사항들 핸들링하기 : POST 요청이 /user/signin 으로 발송이 된다.

    1. POST 를 통해서 ID 와 PW 를 줄 것임 → req.body 에서 해당 내용을 확인해야 한다.

    2. 그렇다면, 해당 req 의 body 는 test case 에서 어떻게 전달되고 있을까?

      이렇게 email 과 password 로 전달되고 있다.

      {
      	email: 'duhyun.kim@codestates.com',
      	password: '1234'
      }
  2. 그렇게req.body.email, req.body.password 를 통해 받은 값을 이제 DB의 records 에 존재하는지 조회해보아야 한다.

    1. 그리고 우리가 user 회원가입 과정에서 중복된 records 들은 block 했기 때문에, findOne API 를 사용하기로 했다.

유저정보확인 기능구현

  1. 특정한 endpoint 로 날아오는 사항들 핸들링하기 : GET 요청이 /user/info 로 발송이 된다.
  2. 해당 요청은 먼저 singin 을 하고 난 뒤 시행하는 기능이다. 그리고, 유저의 session 을 통해서 유저를 판별하고, 유저의 요청에 따른 정보를 제공하는 방식이다.
    1. session 을 구현한다. 구현 시점은 유저가 로그인을 했을 때로.
    2. 구현하는 방법은, express-session 을 사용해서 구현할 수 있도록 한다.
  3. session 을 통해 user 를 판별한다 (session 의 정합성 판단)
    1. 정합성 판단 결과, 아까의 그 유저(로그인을 했던)로 판별되면 → 해당 유저의 모든 records 를 response
    2. 정합성 판단 결과, 아까의 그 유저(로그인을 했던)가 아니라면 → 401 코드와 'unvalid user' 을 response 해준다.

2-2. session 구현하기

express-session

express-session 을 통해 구현한다. express 로 구성한 app.js 에서는 require('express-session'), 그리고 app.use(session) 등으로 미들웨어를 달아놓았으니 그 express 서버와 물려있는 라우터등에서도 session 에 접근할 수 있다.

공식문서를 보았지만 잘 이해되지 않아 velopert 님의 블로그에 나와있는 문서를 참조하였다.

cookie 는 어떻게 설정해 주어야 하는 것일까? 이 곳에서 한 번에 할 수 있는 것인가? 아니면 setHeader 등의 기능을 통해 우리가 일일히 설정해 주어야 하는 것인가? 그것이 감이 오질 않아 일단 console.log(req.session) 을 찍어보았다.

첫번째 가설 : req.session.cookie = { id: req.body.id } 를 통해 session 을 저장할 수 있을까?

→ 실패, 이렇게 하면 express-session 의 초기설정으로 잡아준 cookie 가 전부 날아감(재할당 되었으므로)

Session { cookie: { id: undefined } }

두번째 가설 : `req.session.id = userData.id 와 같이, id 라는 하나의 key 에 우리가 받아온 [req.body.id](http://req.body.id) 를 할당한 값인 userData.id` 를 넣었을 때 어떻게 나오는지 확인해보자!

→ 실패, 변경되지 않음. cookie 를 response 에 써주기 위해서는, express-session 을 사용하는 게 아니라는 결론을 내리고 구글링을 해 봄

새로운 시도 : express - session - cookie 를 통해 유저 정보를 저장하는 과정을 소개한 medium 글을 발견

알게된 것 : express-session 은 session 을 "처리" 하는 용도고, 쿠키를 "write" 해 주기 위해서는 cookie-parser 를 이용해야 한다는 사실을 알았다.

res.cookie('userid',userData.id)

해당 문서의 cookie setting 방법대로 userid 라는 cookie 에 우리가 쿼리문을 통해 찾아온 해당 유저의 table 의 id 값인 justLoggedUser.id를 할당해주었다.

유저 로그아웃 기능구현

  1. 특정한 endpoint 로 날아오는 사항들 핸들링하기 : POST 요청이 /user/signout 으로 발송이 된다.
  2. 해당 요청도 마찬가지로 먼저 singin 을 하고 난 뒤 시행하는 기능이다. 그리고, 유저의 session 을 통해서 유저를 판별하고, 유저의 요청에 따른 정보를 제공하는 방식이다.
    1. session 정보를 없앤다 → req.cookies.useridcookies 로 부터 제거한다.
    2. '/' 로 redirect 시킨다 → res.redirect() 를 통해 구현한다.

4.x API

express 의 redirect 문서

일단은 전부 구현은 했다. 그런데, express-session 을 사용하지 못 했다. 특히 session 과 cookie 간의 이해가 부족해서, cookie 를 통한 session handling 을 어떻게 하는지 모르겠다. 일단은 오늘은 여기서 공부를 마치고 내일 아침 일찍 일어나서 재도전 해야겠다.

오늘 스프린트의 아쉬운 점

cookie parser 를 통해 cookie 를 할당하고, express-sessionreq.session 을 통해 cookie 에 접근해보았으나 되지 않아 cookie-parser 를 통해서 sprint 를 마저 진행함.

~~express-session 의 사용법에 대해서 한 번 짚어주셨으면 좋겠음 → office hour 때 물어보기~~

내가 공식문서를 충분히 읽어보고 정리하면 할 수 있을 것 같다. 일단 시도를 해 보고 도저히 안 되면 물어보자.

profile
правда и красота, truth and beauty

0개의 댓글