로컬 로그인
passport
를 이용하여 로컬 로그인을 구현 할 수 있습니다. 로컬 로그인이란 id
, password
를 통한 회원가입 후 로그인을 할 수 있게 해줍니다.
모듈 설치 및 require
1 | npm install passport |
위 코드를 터미널에 작성하여 필수 모듈을 설치합니다.
- 회원 가입 페이지pug를 사용하여 회원가입 페이지를 구현하였고
1
2
3
4
5
6
7
8
9
10block 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') 회원가입local
회원가입의 경로는/auth/register
으로 지정하였습니다.
아이디, 비밀번호, 닉네임을 넣어주고 회원가입 버튼을 누르면POST
요청으로 회원가입 되게 됩니다. - 로그인 페이지
1
2
3
4
5
6
7block 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
18const 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
앞에 선언되게 되면serialize
후user
의 정보가 담기지 않고 초기화 되기 때문에 꼭 순서를 확인하시고 코딩하시기 바랍니다. - 회원가입
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16router.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
,nickname
이body
에 담겨 들어오게 되면 바디파서를 통해 각 변수에 담아줍니다. 쿼리를 통해user_id
가 중복되었는지 확인하고 중복되었다면 이미 사용중인 아이디가 있습니다.라는 에러를 표출해줍니다. 만약에user_id
가 중복되지 않는다면 새로운 아이디를 생성 후 로그인페이지로 리다이렉트 시켜줍니다. 비밀번호는 보안으로bcrypt
를 사용하였습니다. - 로그인로그인 라우터를 통해 들어온 정보는
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16router.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
4router.post('/login', passport.authenticate('local', {
successRedirect: '/',
failureRedirect: '/auth/login'
}));Custom
바랍니다.1
2
3
4
5
6passport.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
3passport.serializeUser((user, done) => {
done(null, `${user.user_id}:${user.nickname}`)
})Passport Serializer
로 전달되면user정보
를Session
에 저장합니다.1
2
3
4
5
6
7
8
9
10
11passport.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
의 정보가 맞는지 확인하게 됩니다.