passport-local

로컬 로그인

passport를 이용하여 로컬 로그인을 구현 할 수 있습니다. 로컬 로그인이란 id, password를 통한 회원가입 후 로그인을 할 수 있게 해줍니다.

모듈 설치 및 require

1
2
3
4
5
npm install passport
npm install passport-local
npm install cookie-session
npm install bcrypt
npm install express

위 코드를 터미널에 작성하여 필수 모듈을 설치합니다.

  • 회원 가입 페이지
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    block body
    h1 회원가입
    form(action='/auth/register', method='post')
    input(type='text', placeholder= '아이디', name='user_id')
    br
    input(type='password', placeholder= '비밀번호', name='password')
    br
    input(type='text', placeholder= '닉네임', name='nickname')
    br
    button(type='submit') 회원가입
    pug를 사용하여 회원가입 페이지를 구현하였고 local 회원가입의 경로는 /auth/register으로 지정하였습니다.

    아이디, 비밀번호, 닉네임을 넣어주고 회원가입 버튼을 누르면 POST요청으로 회원가입 되게 됩니다.
  • 로그인 페이지
    1
    2
    3
    4
    5
    6
    7
    block body
    h1 로그인
    p Local 로그인
    form(action='/auth/login', method='post')
    input(type='text', placeholder= '아이디', name='user_id')
    input(type='password', placeholder= '비밀번호', name='password')
    button(type='submit') 로그인
    pug를 사용하여 로그인 페이지를 구현하였고 로그인 경로는 /auth/login으로 지정하였습니다.

    아디와 비밀번호를 넣어주고 로그인 버튼을 누르면 POST요청으로 로그인 요청이 가고 조건에 충족되면 로그인 됩니다.
  • Passport 로직 구현
    기본설정
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    const passport = require('passport')
    const LocalStrategy = require('passport-local').Strategy
    const bcrypt = require('bcrypt')
    const express = require('express')
    const cookieSession = require('cookie-session')
    const app = express()
    const router = express.Router()
    router.use(cookieSession({
    name: 'localPassport',
    keys: [
    process.env.SESSION_SECRET
    ],
    cookie: {
    maxAge: 1000 * 60 * 60 * 24 // 유효기간 1일
    }
    }))
    router.use(passport.initialize())
    router.use(passport.session())
    위 설정을 해주면 기본설정은 끝났습니다. 여기서 가장 중요한 부분은 router.use(passport.initialize())router.use(passport.session())가 꼭 쿠키세션 다음에 선언되어야 합니다. cookieSession 앞에 선언되게 되면 serializeuser의 정보가 담기지 않고 초기화 되기 때문에 꼭 순서를 확인하시고 코딩하시기 바랍니다.
  • 회원가입
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    router.post('/auth/register', (req, res) => {
    const user_id = req.body.user_id,
    password = bcrypt.hashSync(req.body.password, 10),
    nickname = req.body.nickname
    query.checkAlreadyJoinId({user_id})
    .then(matched => {
    if (matched) {
    throw new Error ('이미 사용중인 아이디가 있습니다.')
    } else {
    query.createUser({user_id, password, nickname})
    .then(() => {
    res.redirect('/auth/login')
    })
    }
    })
    })
    /auth/register의 경로롤 user_id, passport, nicknamebody에 담겨 들어오게 되면 바디파서를 통해 각 변수에 담아줍니다. 쿼리를 통해 user_id가 중복되었는지 확인하고 중복되었다면 이미 사용중인 아이디가 있습니다.라는 에러를 표출해줍니다. 만약에 user_id가 중복되지 않는다면 새로운 아이디를 생성 후 로그인페이지로 리다이렉트 시켜줍니다. 비밀번호는 보안으로 bcrypt를 사용하였습니다.
  • 로그인
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    router.post('/login', (req, res, next) => {
    passport.authenticate('local', (err, user, info) => {
    if (err) {
    return next(err)
    }
    if(!user) {
    throw new Error ('아이디와 비밀번호를 입력해주세요.')
    }
    req.logIn(user, err => {
    if (err) {
    return next(err)
    }
    res.redirect('/auth/success')
    })
    })(req, res, next)
    })
    로그인 라우터를 통해 들어온 정보는 LocalStrategy로 전달됩니다.
    1
    2
    3
    4
    router.post('/login', passport.authenticate('local', {
    successRedirect: '/',
    failureRedirect: '/auth/login'
    }));
    로그인 라우터는 위 코드처럼 간단하게 사용 가능합니다. 사용 조건에 따라 Custom 바랍니다.
    1
    2
    3
    4
    5
    6
    passport.use(new LocalStrategy({ usernameField: 'user_id' }, (user_id, password, done) => {
    query.checkAlreadyJoinId({user_id})
    .then(matched => {
    (matched && bcrypt.compareSync(password, matched.access_token))? done(null, matched) : done(new Error('아이디 또는 패스워드가 일치하지 않습니다.'))
    })
    }))
    LocalStrategy로 전달되면 쿼리를 통해 user의 정보를 확인하고 bcrypt를 통해 비밀번호를 비교합니다. 비교된 결과가 모두 조건에 맞으면 Passport Serializer로 전달됩니다.
    1
    2
    3
    passport.serializeUser((user, done) => {
    done(null, `${user.user_id}:${user.nickname}`)
    })
    Passport Serializer로 전달되면 user정보Session에 저장합니다.
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    passport.deserializeUser((user, done) => {
    const [user_id, nickname] = user.split(':')
    query.getLocalUserById({user_id, nickname})
    .then(user => {
    if (user) {
    done(null, user)
    } else {
    done(new Error('해당 정보와 일치하는 사용자가 없습니다.'))
    }
    })
    })
    Passport Deserializser에선 페이지 이동시마다 user의 정보가 맞는지 확인하게 됩니다.
공유하기