[Express.js] Passport 모듈을 활용한 카카오 소셜 로그인 구현

2024. 6. 27. 16:41·Back-end/Node.js
목차
  1. Passport란?
  2. 1. Kakao Developers에서 애플리케이션 생성
  3. 2. Passport 분석
  4. 3. router에 적용
반응형

Passport란?

Passport는 이름 그대로 서비스를 사용할 수 있게끔 해주는 여권 같은 역할을 하는 모듈이다.

회원가입과 로그인은 직접 구현할 수도 있지만, 세션과 쿠키 처리 등 복잡한 작업이 많으므로 검증된 모듈을 사용하는 것이 좋다.

그런 방면에서, Passport는 사용하기 좋은 검증된 모듈이다.

 

특히 facebook이나 kakao, google 같은 소셜 로그인 시에  passport 모듈이 사용된다.

 

1. Kakao Developers에서 애플리케이션 생성

카카오 디벨로퍼에서 내 애플리케이션 -> 추가하기를 눌러 앱을 생성한다

 

이렇게 애플리케이션을 생성하면 앱 설정 -> 앱 키에서 REST API 키를 확인할 수 있는데, 추후에 kakao Strategy에 사용될 API KEY이므로 env 파일에 잘 저장해두자!

2. Passport 분석

이제 해당 애플리케이션에 로그인하기 위한 절차를 살펴보자!

 

1. passport / index.js

먼저, passport 모듈을 사용하기 위한 configuration 코드이다.

const passport = require("passport");
const Member = require("../models/member");
const kakao = require('./kakaoStrategy');


module.exports = () => {
    kakao();

    passport.serializeUser((user, done) => { // 첫 로그인 시 session 저장
        done(null, user.kakaoId);
    });

    passport.deserializeUser((id, done) => { // 이후 로그인 시 세션 불러오기. req.user로 접근 가능!
        Member.findOne({ kakaoId: id })
            .then(member => done(null, member))
            .catch(err => done(err));
    });
}
  • serializeUser는 사용자가 로그인할 때 호출된다. 여기서 사용자 객체에서 user.kakaoId 속성을 세션에 저장한다.
  • done(null, user.kakaoId): 첫 번째 인자인 null은 에러가 없음을 나타내고, 두 번째 인자인 user.kakaoId는 세션에 저장할 사용자 식별자를 나타낸다.

 

  • deserializeUser는 세션에 직렬화된 사용자가 있는 모든 요청에서 호출된다. 세션에 저장된 kakaoId를 받아 데이터베이스에서 해당 사용자를 찾는다.
  • Member.findOne을 통해 일치하는 사용자가 발견되면 done(null, member)가 호출되고, 이 사용자 객체는 req.user로 접근 가능해진다.
  • 에러가 발생하거나 일치하는 사용자를 찾지 못한 경우, 에러 객체와 함께 done(err)가 호출된다.

 

 

2. passport / kakaoStrategy.js

passport 모듈을 사용하기 위한 전략이다. google, facebook 등 다양한 소셜 로그인이 있지만 여기에선 passport-kakao를 사용하기 때문에 카카오 전략만 살펴볼 예정이다.

const passport = require("passport");
const KakaoStrategy = require('passport-kakao').Strategy;

const Member = require('../models/member')

module.exports = () => {
    passport.use(new KakaoStrategy({
        clientID: process.env.KAKAO_APIKEY, // 카카오에서 발급해주는 아이디
        callbackURL: process.env.REDIRECT_URL, // 카카오 인증 결과 라우터 주소
    }, async (accessToken, refreshToken, profile, done) => {
        try {
            // 기존에 카카오를 통해 회원 가입한 사용자가 있는지 조회
            const exUser = await Member.findOne({ kakaoId: profile.id });
            if (!exUser) { // 있으면 사용자 정보와 함께 done 함수를 호출하고 종료
                // 없으면 회원 가입 진행
                // 인증 후 콜백 라우터로 accessToken, refreshToken과 profile을 보냄.
                const newUser = await Member.create({
                    kakaoId: profile.id
                });
                return done(null, newUser);
            }
            return done(null, exUser);
        } catch (error) {
            done(error);
        }
    }));
}

 

Passport.js의 카카오 OAuth 전략을 설정하여 사용자가 카카오 계정을 통해 로그인할 수 있도록 하는 코드이다.

 

env 파일에 등록해둔 카카오 APIKEY와 CallbackURL을 사용하여 구현할 수 있다.

 

이렇게 만들어둔 카카오 전략을 그대로 사용 가능하다.

3. router에 적용

const express = require('express')
const passport = require('passport')
const authRouter = express.Router()
const { logout} = require('../controller/authController')
const Member = require("../models/member");
const {generateToken, verifyToken} = require("../util/auth/jwtHelper");
require('dotenv').config()


// 로그인 인가 요청
authRouter.get("/login", (req, res, next) => {
    try {
        const token = req.headers.authorization;
        req.token = verifyToken(token);

        return res.status(200).json({
            msg: "success",
            token : token
        })
    } catch(error) {
        return next();
    }
}, passport.authenticate("kakao"));

// 로그인 콜백 요청
authRouter.get(
    "/login/callback", passport.authenticate('kakao'), (req, res, next) => {
        try {
            const user = req.user;

            if (!user) {
                return res.status(400).json({
                    msg: "사용자가 존재하지 않음."
                })
            }

            if (user.name === null) {
                // 회원가입으로!
                return res.status(200).json({
                    msg : "sign_up",
                    kakaoId: user.kakaoId
                })
            } else {
                const token = generateToken(user);
                // 메인 화면으로!
                return res.status(200).json({
                    msg: "success",
                    token : token
                })
            }
        } catch (error) {
            next(error);
        }
    }
);

 

 

반응형

'Back-end > Node.js' 카테고리의 다른 글

[2023-2 WINK Project] 2. MongoDB 사용하기  (0) 2024.05.01
[2023-2 WINK Project] 1. Express 시작하기  (3) 2024.04.20
  1. Passport란?
  2. 1. Kakao Developers에서 애플리케이션 생성
  3. 2. Passport 분석
  4. 3. router에 적용
'Back-end/Node.js' 카테고리의 다른 글
  • [2023-2 WINK Project] 2. MongoDB 사용하기
  • [2023-2 WINK Project] 1. Express 시작하기
류건
류건
개발 일지
  • 류건
    건's Dev
    류건
  • 전체
    오늘
    어제
    • 분류 전체보기 (96)
      • Back-end (56)
        • Spring (31)
        • Nest.js (3)
        • Next.js (2)
        • Node.js (3)
      • Infra & Cloud (21)
        • Cloud Computing (6)
        • Docker (3)
        • AWS (7)
      • Java (2)
      • Computer Science (12)
        • Computer Network (0)
        • Operating System (0)
        • 정보 보호와 시스템 보안 (12)
        • Software Architecture (0)
      • 회고록 (4)
        • 우아한테크코스 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    nginx
    aws
    Kafka
    티스토리챌린지
    Webflux
    express.js
    Github Actions
    고가용성
    CORS
    Lock
    db
    Nest.js
    보안
    오블완
    WebClient
    ssl
    public key
    어노테이션
    EC2
    JPA
    Docker
    JWT
    정보보호
    CI/CD
    https
    Spring
    node.js
    Spring Boot
    ddl-auto
    CD
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.0
류건
[Express.js] Passport 모듈을 활용한 카카오 소셜 로그인 구현
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.