개요

Express는 Javasciprt환경에서 간단한 웹페이지 구축을 위해 사용되는 프레임워크이다.

설치

npm init express

Hello World

const express = require('express') // express 모듈을 사용할 것이다.
const app = express()
const port = 3000 // 사용할 포트는 300번
app.get('/', (req, res) => res.send('Hello World!')) 

HTTP의 방식은 크게 GETPOST로 나뉘어 진다. 이때 URL의 / 부분부터 시작되는 경로를 찾아가는 것을 express 에서는 라우팅 이라고 한다. (네트워크에서의 라우팅이 아니다!!) 이 말은 만약 / (즉 메인 URL)로 시작되는 경로가 서버에 GET방식으로 전송될경우 response를 안냥! 이라고 보내고 싶다 이다.

app.listen(port, () => console.log(`Example app listening on port ${port}!`)) //포트에 바운딩

정적 파일 서비스

정적 파일이란 이미지나 텍스트처럼 변하지 않는 파일을 말한다.

app.use(express.static('public')) // -> http://localhost:3000/images/kitten.jpg 로 접근
res.send('<img src="/index.jpg">') 로 파일을 전송

를 먼저 해주어야 한다. 이는 public 이라는 폴더를 사용하여 서비스를 제공하겠다는 의미이다. 이때 express.static 은 폴더에 저장된 파일을 검색하는 함수로써. express.static 미들웨어 함수를 이용해 정적 디렉토리를 설정한 순서대로 파일을 검색한다.

만약 여기서 epxress.static 을 가상적인 경로를 통해서 접근하고자 한다면

app.use('/static', express.static('public')) // -> http://localhost:3000/static/images/kitten.jpg 로 접근

이라고 하면 된다.

웹페이지의 서비스

정적 파일의 전송

변하지는 않는 웹서비스를 보여주고 싶을때 사용한다. HTML파일을 직접 전송하면 된다.

동적 파일의 전송

변하는 웹서비스를 보여줄때 사용한다. HTML에 동적인 변수를 할당하여 전송하게 된다.

템플릿 엔진

템플릿 엔진 참고

npm install pug --save 로 express 에 템플릿 엔진을 설치
app.set('view engine', 'pug') express 에 어떤 템플릿 엔진을 사용할지 알려줌
app.get('/template',function(req,res) {
res.render('템플릿 파일 이름', { 변수명:'변수값' (JSON 파일 포맷)}); 지정된 render 엔진을 이용하여 웹페이지 렌더링

GET 방식의 정보 전달

Query String

쿼리 스트링이란 URL뒤에 붙는 문자열이다. http://example.com/temp?id=1 에서 id=1 이 쿼리 스트링이다.

appt.get('/temp', function(req, res) {
res.send(req.query.id); //이 부분이 req 란 객체를 통해서 들어오는 query 변수중에 id란 value를 담게 된다. 
})

Semantic URL

appt.get('/temp/:id', function(req, res) {
res.send(req.params.id); //이 부분이 req 란 객체를 통해서 들어오는 params 변수중에 id란 value를 담게 된다. 
})

POST 방식의 정보 전달

npm install body-parser 을 이용해서 body parser 미들웨어를 추가한다. 

이후에 적절한 body parser 설정을 완료한후 애플리케이션에서

req.body."포스트 방식의 키값 변수명" 을 통해서 접근해 가져온다.

파일 업로드

multer란 라이브러리를 이용하여 파일을 업로드 한다.

npm install --save multer (멀터 추가)

쿠키 사용

npm install cookie-parser 을 통해서 미들웨어를 등록해준다. 
app.use(cookieParser())

res.cookie() 메소드는 쿠키 옵션을 설정할 수 있다.

옵션 설명
maxAge 만료 시간 설정 (밀리초 단위)
epxires 쿠키의 만료시간을 GMT시간으로 설정
path 쿠키 경로 설정
domain 쿠키의 도메인 이름
secure HTTPS에서만 쿠키 사용 가능하게 만듬
httpOnly http 로만 쿠키에 접근하도록 함
signed 쿠키가 서명되어야 할 지를 설정
req.cookie.{object_name} 에 쿠키 값이 저장된다. 
res.cookie(key, value) 로 쿠키게 값을 설정한다. 

서명된 쿠키는 값에 서명이 첨부된 쿠키이다. 서명은 특정 문자열에 의해 생성된다.

appe.use(cookieParser('String For Sign')) 어떤 문자열로 쿠키를 서명할지 결정한다. 
res.cookie(key, value, {singed: true, maxAge: 10000}) => 위에서 서명한 문자열로 암호화한 쿠키값을 전송한다. 

서명된 쿠키는 다음에 의해 삭제한다.

생성 삭제
res.cookie('visitors', 100); res.clearCookie('visitors');
res.cookie('visitors', 100, {path: '/visitors'}) res.clearCookie('visitors', {path: '/visitors'})
res.cookie('visitors', 100, {sign : true}); res.clearCookie('visitors')
  1. 쿠키는 문자열로 저장되기 때문에 만약 value가 숫자라면 parseInt() 로 숫자로 파싱해야 한다.
  2. 서명된 쿠키는 res.cookies 가 아닌 res.singedCookies 로 값을 읽는다.

세션

설치및 설정

npm install express-session 
var session = require('express-session')
app.use(session({
 secret: 쿠키를 암호화할 인증 값
 resave: 세션을 언제나 저장할지 (false 가 권장됨)
 saveUninitialized 세션을 저장하기 전에 초기화 되지 않은 상태로 미리 만들어서 저장 (true가 권장됨)

세션으로의 접근은 session변수명을 사용

sess = req.session
sess.{key_name} = string //따로 키를 추가할 필요 없이 키를 설정 (이 키는 서버에 저장됨)
sess.{key_name} 으로 세션을 불러옴

세션의 로그아웃

req.session(destory(callback(error){})

보안

비밀번호

비밀번호를 저장할때 그냥 저장하게 되면, 나중에 데이터베이스가 노출될시 사용자들의 비밀버호가 노출될 수 있다. 즉 이런 경우를 대비하기 위해서 비밀번호를 암호화한뒤 저장하고 비교해야 한다. 이때 만약 그냥 정보를 암호화하게 되면 기존 준비해논 해쉬 테이블과 비교하여 값을 알아낼 수도 있다. 이 문제를 보완하기 위해서 salt를 이용한다. salt는 임의의 긴 문자열로, 사용자의 비밀번호와 salt값을 더한뒤 암호화 하여 위의 문제를 보안한다. salt값은 사용자의 아이디를 이용하여 만들면, 같은 비밀번호를 사용하더라도, 다른 해쉬값을 생성하게 하여 더욱 보안에 신경을 쓸 수 있다.

종류

  1. md5
  2. PBKDF2
  3. SHA256

Passportjs

npm install passport
npm install passport-{원하는 vendor의 패스포트 모듈}
var passport = require('passport')
var LocalStartegy = require('passport-...').Strategy;

또한 반드시 세션기능을 사용해 주어야 한다. 패스포트를 사용하기 위한 기본 설정이다.

app.configure(function() {
 app.use(express.static('public'))
 app.use(express.cookieParser())
 app.use(express.bodyParser())
 app.use(express.session({ secret: "some string' }))
 app.use(passport.initialize())
 app.use(passport.session())
 app.use(app.router)
})

원하는 라우터 주소로 접근시 아래의 콜백함수를 실행 시킨다. 이때 이 콜백함수는 정의된 Strategy 함수를 이용해 정보를 처리한다.

app.post('원하는 로그인 라우터 주소', passport.authenticate('strategy 이름', {
successRedirect: '성공하면 갈 페이지',
faliureRedirect: '실패하면 갈 페이지',
failureFlash: 실패할 경우 실패 표시
}))

Strategy 함수는 다음과 같이 정의한다.

passport.use(new LocalStrategy(
 function(username, password, done) {
  로그인처리 함수
  성공시 done(null, user) (객체를 리턴하면 성공함 - 보통 user 객체를 리턴)
  실패시 done(null, false) (false를 리턴하면 실패함)

만약 done의 두번째 인자가 false가 아니면

passport.serializedUser(function(user, done) {
 done(null, user.id) // 혹은 user.{some string for identification}
})

가 실행하도록 약속되어 있다. 즉 user란 객체에는 사용자에 대한 식별자가 필요하다. 혹시 만약 id를 부여하지 않았다면 user마다 다른 식별자를 통해서 session을 성립할 키를 주어야 한다.

passport(deserializeUser(function(id, done) {
 User.findById(id, function(err, user) {
  id값이랑 사용자의 세션이랑 일치하는 사람이 있는지 검사
  있으면
   done(err, user);
 })
})

로그아웃은

req.logout()
req.session.save(()=>{} /* 실행할 함수명 */ )