Authentication & Security (2)

김주언·2022년 6월 7일
0

WEB - Basic

목록 보기
9/10
post-thumbnail

Passport.js

Passport는 클라이언트의 요청을 authenticate 해주는 미들웨어이다.

passport.js 패키지를 사용하여 패스워드 암호화한다.
이전 게시글의 기본 설정을 유지한다.

Install

$ npm install passport
$ npm install passport-local-mongoose

mongoose를 사용하고 있기 때문에 passport-local-mongoose를 설치한다.

require('dotenv').config();
const express = require('express');
const bodyParser = require('body-parser');
const ejs = require('ejs');
const mongoose = require('mongoose');
const passport = require('passport');
const passportLocalMongoose = require('passport-local-mongoose');

const userSchema = new mongoose.Schema({
  email: String,
  password: String,
});

// mongoose API의 Schema는 플러그인을 추가할 수 있다.
userSchema.plugin(passportLocalMongoose);

Verify Password

Strategies

Strategies는 요청에 대한 인증 매커니즘을 수행한다.

  • 인증 매커니즘은 요청에서 전달받은 데이터의 자격 증명을 인코딩하는 방법을 정의한다.
  • 해당 자격 증명을 확인하는 데 필요한 절차를 지정
  • 자격 증명이 성공적으로 확인되면 요청이 인증된다.
  • passport 사용에 있어 전략을 구성, 등록하는 절차가 필수적

.use()로 전략 등록하기

const User = mongoose.model('User', userSchema);
// 전략을 직접 구성하지 않고, createStrategy() 메서드를 이용하여 자동 생성한 후 등록
passport.use(User.createStrategy());
  • createStrategy() : 미리 설정이 완료된 passport-local LocalStrategy 인스턴스를 생성한다.

authenticate(password, [cb])

  • 유저 객체를 인증한다. 콜백함수 지정하지 않으면 Promise 반환함
  • passport의 전략(passport-local LocalStrategy)에 사용된 함수를 생성한다.

register(user, password, cb)

  • 주어진 password로 새로운 유저 객체를 생성한다. user가 중복되는지 확인한다.
app.post('/register', (req, res) => {
  // req에서 전달받은 username과 password를 사용하여 유저 객체를 DB에 등록한다.
  User.register(
    { username: req.body.username },
    req.body.password,
    function (err, user) {
      if (err) {
        console.log(err);
      } else {
        // 이미 존재하는 유저일 경우 인증요청
        // 아이디와 패스워드가 일치하면 시크릿 페이지로
        passport.authenticate('local')(req, res, function () {
          res.redirect('/secrets');
        });
      }
    }
  );
});

app.post('/login', (req, res) => {
  const user = new User({
    username: req.body.username,
    password: req.body.password,
  });

  req.login(user, function (err) {
    if (err) {
      console.log(err);
    } else {
      // 'local' 전략 사용, 함수 반환
      passport.authenticate('local')(req, res, function () {
        res.redirect('/secrets');
      });
    }
  });
});

createStrategy > passport.use(LocalStrategy) > authenticate


세션 등록

로그인 후 로그아웃 구현을 위해 세션 사용
세션 등록하는 위치 중요!

npm i express-session
const session = require('express-session');

app.use(express.static('public'));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({ extended: true }));
// 세션 등록
app.use(
  session({
    secret: 'keyboard cat',
    resave: false,
    saveUninitialized: true,
  })
);

// passport 초기화
app.use(passport.initialize());
// passport 초기화 후 세션 등록
app.use(passport.session());

// ... 

passport.serializeUser(User.serializeUser());
passport.deserializeUser(User.deserializeUser());

세션 활용

로그인 유지

isAuthenticated() 클라이언트가 보낸 req에 세션이 유지되어 있는지 확인하고 인증된 상태라면 바로 비밀페이지로 이동가능하다.
세션이 끊겼으면 비밀페이지를 요청하더라도 로그인 페이지로 이동한다.

app.get('/secrets', (req, res) => {
  if (req.isAuthenticated()) {
    res.render('secrets');
  } else {
    res.redirect('/login');
  }
});

로그아읏

logOut() 메서드로 간단하게 구현가능하다. 세션을 종료하고 메인 페이지로 돌아간다.

app.get('/logout', function (req, res) {
  req.logOut();
  res.redirect('/');
});
profile
학생 점심을 좀 차리시길 바랍니다

0개의 댓글