4. Node 프로젝트 가계부 만들기 (로그인, passport, jwt 사용)

2021. 5. 25. 14:42프로젝트/가계부 - 초기 개발

  1. passport를 이용해서 로그인
  2. jwt를 이용하여 인증

유저를 계속확인하기위해 디비에 요청하는 작업은 자원 낭비이기 때문에 jwt를 이용하여 로그인 횟수를 줄일 수 있다

 

깃 주소 : github.com/wls0/account_book/blob/master/routes/user.js

 

passport를 설치 한다.

npm install passport passport-local 

passport 설정

1. id, password를 프론트에서 받는다.

2. 유니크 키인 id를 이용하여 해당 유저의 디비를 찾는다.

3. 유저의 비밀번호가 맞는지 crypto을 이용해 해당 패스워드와 salt값을 합쳐 디비에 저장된 비밀번호와 같은지 확인 한다.

4. 맞다면 done(null, data)로 유저 정보를 전달한다.

 

jwt

jwt 설명 : crispypotato.tistory.com/58

jwt 설치

npm i jsonwebtoken

jwt에는 유저 아이디, 비밀번호를 넣으면 안되고, 유저 인덱스 값이나 구별 할 수 있는값을 넣어주면 된다.

그리고 jwt가 인증이 유지하는 시간을 정해 줄 수 있다.

지금은 일단 30일동안 유지하도록 만든다.

로그인, 로그인 실패시 이동

1. passport에서 로그인을 확인하고 아이디, 비밀번호가 다 맞다면 /login으로 이동하고, 틀리면 /fail로 이동.

2. jwt를 이용하여 30일 동안 유효하게 설정하여 token에 담아 프론트로 상태코드와 토큰 내용을 보내 준다.

const express = require('express')
const router = express.Router()
const models = require('../models')
const User = models.account_users
const crypto = require('crypto')
const passport = require('passport')
const LocalStrategy = require('passport-local').Strategy
const jwt = require('jsonwebtoken')
const secret = require('../config/pwd.json')
const err = require('../lib/error').errorCode

passport.use(new LocalStrategy({
  usernameField: 'id',
  passwordField: 'password'
},
async (id, password, done) => {
  const data = await User.findOne({ where: { userId: id } })
  if (data) {
    const pwd = crypto.createHash('sha512').update(password + data.salt).digest('hex')
    pwd === data.password ? done(null, data) : done(null, false)
  } else {
    return done(null, false)
  }
}
))

// 로그인 시 토큰 발행
router.post('/login',
  passport.authenticate('local', { failureRedirect: '/user/fail', session: false }),
  async (req, res, error) => {
    
    const user = req.user
    const accessToken = jwt.sign({
      id: user.id
    }, secret.jwtPwd,
    {
      expiresIn: '30d',
      issuer: 'localhost',
      subject: 'user_info'
    })
    const token = { access_token: accessToken }
    res.cookie('user', token, { httpOnly: true, maxAge: 30 * 24 * 60 * 60 * 1000 })
    err(res, 200, '', token)
  })

// 로그인시 아이디,비밀번호가 틀렸을때
router.get('/fail', (req, res, next) => {
  err(res, 401, '아이디혹은 비밀번호가 틀렸습니다.')
})
728x90
반응형