본문 바로가기
카테고리 없음

PASSPORT 인증모듈

by 잘먹는 개발자 에단 2025. 5. 7.

## 개요

- 회원가입과 로그인을 직접 구현할 수 있지만, 허점이 있을 수 있고 세션이나 쿠키 처리 등의 이유로 복잡하기에 미리 만들어진 검증된 모듈을 사용하는 것이 권장된다. 

 

- Passport는 이에 적합한 미들웨어 모듈이다. 

말 그대로 여권이라는 의미인데, 여권 소지자가 입출국 자격에 대해서 인증하듯이, 우리가 요청/응답을 받을 때도 이 모듈을 사용하여 인증을 받을 수 있다. 

 

- 로컬 계정 ( 이메일/비밀번호 )부터 구글, 카카오, 네이버, 깃허브 같은 소셜 로그인까지 모두 지원된다. 

- 이런 인증방식 하나하나를 전략 strategy라고 한다.

- 공식문서 : https://www.passportjs.org/

 

Passport.js

Simple, unobtrusive authentication for Node.js

www.passportjs.org

 

 

### 주요개념

- Strategy 전략

인증방식을 말한다.

passport-local (이메일,비번)

passport-google-oauth20 (구글)

passport-kakao (카카오)

 

- serializeUser / deserializeUser

로그인 성공 후에, 사용자 정보를 세션에 저장하거나 불러올 때 사용한다.

예를 들어서 db에서 꺼낸 객체 -> 세션에 id만 저장 -> 요청 들어올 때 id로 다시 user 꺼내오기

 

- req.login / req.logout / req.isAuthenticated

로그인, 로그아웃, 로그인 상태 확인할 때 쓰는 메서드

 

npm install passport passport-local express-session

 

 

### 로컬 로그인 기준 예제코드 

const express = require('express');
const passport = require('passport');
const LocalStrategy = require('passport-local').Strategy; // local 전략 가져오기 
const session = require('express-session'); // 세션 미들웨어

const app = express();

// 미들웨어 설정
app.use(express.urlencoded({extended : false})); // form 데이터 파싱
app.use(session({secret:'secret', resave : false, saveUninitialized : false})); // 세션 설정
app.use(passport.initialize()); // pass초기화
app.use(passport.session()); // passport 세션 연결

// 사용자 db 예시 ( 실제로는 db연결 필요 ) 
const users = [{id : 1, username:'test', password:'1234'}];

// local 전략 정의
passport.use(new LocalStrategy((username, password, done) => {
	const user = users.find(u=> u.username === username );
    
    if(!user) return done(null, false, {message:'사용자 없음'});
    if( user.password !== password ) return done(null, false, { message : '비밀번호 틀림' });
    return done(null, user);
}));


// 사용자 세션 저장
passport.serializeUser((user,done) => {
	done(null, user.id); // user.id만 세션에 저장	
});

// 사용자 세션에서 꺼내기
passport.deserializeUser((id, done) => {
	const user = users.find(u=> u.id === id);
    done(null, user);
});

app.post('/login', passport.authenticate('local', {
	successRedirect: '/success', // 성공 시 이동할 경로
    failureRedirect : '/fail' // 실패 시 이동할 경로
}));


app.get('/success', (req, res) => res.send('로그인 성공!'));
app.get('/fail', (req, res) => res.send('로그인 실패 ㅠㅠ'));

// 서버 실행
app.listen(3000, () => console.log('서버 실행 중'));

 

 

사용자 요청이 왔을 때 처음 실행되는 부분은 '/login' 엔드포인트의 post 메서드다. 

 

이후에 바로 passport.authenticate('local', {...}); 미들웨어가 실행된다. 

 

 

### 그럼 이후에 passport.authenticate('local') 안에서는 무슨 일이 일어날까?

 

- 여기서 passport-local 전략이 불려서 실행된다.

- 이 전략 안에서 자동으로 req.body.username과 req.body.password를 꺼내서 가져오게 된다. 

- LocalStrategy 기본 옵션이 아래와 같이 되어있기 때문이다.

usernameField:'username',
passwordField:'password'

 

 

- LocalStrategy 가 정의된 코드를 보면, 실제로는 이곳에서 db쿼리 로직이 들어가면 된다. 아래와 같은 예시를 들 수 있다. 

passport.use(new LocalStrategy({
  usernameField: 'id',    // req.body.id 로부터 가져옴
  passwordField: 'pw'     // req.body.pw 로부터 가져옴
}, (username, password, done) => {
  // 예: MySQL 쿼리 날리는 부분
  db.query('SELECT * FROM users WHERE username = ?', [username], (err, results) => {
    if (err) return done(err); // 쿼리 에러
    
    if (results.length === 0) {
      return done(null, false, { message: '사용자 없음' }); // 유저 없음
    }

    const user = results[0];

    if (user.password !== password) {
      return done(null, false, { message: '비밀번호 틀림' }); // 비번 틀림
    }

    return done(null, user); // 성공 → user 객체 넘김
  });
}));

 

 

### 자 그럼 이런 의문이 들 수 있다. 아 그러면 passport를 사용하면 알아서 jwt 액세스 토큰부터 리프레시 토큰까지 알아서 해주는건가?..

 

- 결론은 그렇지 않다이다.

- passport-local 전략은 아주 단순하게

    - 사용자 id/pw 받아서, db에서 확인하고, 맞으면 done(null, user) 호출, req.login()으로 세션에 user정보 저장 이게 전부다. 

- 세션 기반 로그인이라서, 서버는 user 정보를 메모리나 redis 같은데 저장하고 클라이언트는 세션 쿠키 ( connect.sid )를 들고 다니면서 인증을 한다.