본문 바로가기
프로그램 (PHP,Python)

Google OAuth2 인증을 Node.js에서 간단하게 구현하는 방법

by 날으는물고기 2024. 4. 28.

Google OAuth2 인증을 Node.js에서 간단하게 구현하는 방법

Google OAuth2 인증을 Node.js에서 간단하게 구현하는 방법을 단계별로 정리합니다. Passport의 Google Strategy를 사용하는데, Passport는 Node.js를 위한 인증 미들웨어로, Express 기반 웹 애플리케이션에 쉽게 통합할 수 있습니다. 사용자 이름과 비밀번호, Facebook, Twitter 등 다양한 방식을 지원합니다.

Google 자격증명 얻기

  1. Google 개발자 콘솔(Google Developer Console)에 접속해 새 프로젝트를 생성합니다.
  2. 프로젝트를 선택하고 '자격증명'으로 이동한 뒤 'OAuth 클라이언트 ID'를 선택합니다.
  3. 애플리케이션 유형으로 '웹 애플리케이션'을 선택합니다.
  4. 애플리케이션 이름을 입력하고, '승인된 JavaScript 원본'에 http://localhost:3000을, '승인된 리디렉션 URI'에 http://localhost:5000/auth/google/callback을 추가한 후 생성 버튼을 클릭합니다.
  5. Google 클라이언트 ID와 Google 클라이언트 시크릿을 복사합니다.

새 프로젝트 초기화

  • 새 폴더를 생성하고 Visual Studio Code(또는 다른 IDE)에서 폴더를 열어 아래 명령어를 실행합니다.
    npm init
  • 프로젝트 이름 등의 상세 정보를 입력하거나 기본 설정을 사용합니다. package.json 파일이 생성됩니다.

프로젝트 구조

  • 참조 이미지에 따라 폴더와 파일을 생성합니다. node_modules, package-lock.json, package.json은 자동으로 생성됩니다.

의존성 설치

  • 프로젝트에 필요한 의존성을 설치합니다.
    npm i ejs connect-mongo dotenv express-session mongoose passport passport-google-oauth20

앱 실행 설정

  • Nodemon을 설치하여 파일 변경 시 서버가 자동으로 재시작되도록 설정합니다.
    npm i -D nodemon
  • package.jsonscripts 섹션을 아래 코드로 변경합니다.
    "scripts": {
      "start": "node app.js",
      "dev": "nodemon app.js"
    }

로컬 서버 시작

  • 개발/테스트용 앱을 시작하기 위해 아래 명령어를 실행합니다.
    npm run dev

구성 및 인증 설정

  • Google 클라이언트 ID와 시크릿을 config/config.env 파일에 설정합니다.
  • MongoDB URI를 설정합니다. (예: mongodb://localhost:27017/ 또는 MongoDB Atlas 사용 시 해당 URI)

애플리케이션 코드

  • app.js에 서버를 설정하고, routesmiddleware를 구성합니다.
  • Passport Google Strategy를 설정하고, 사용자 모델(models/User.js)을 생성합니다.
  • 로그인 및 메인 페이지(views/login.ejs, views/index.ejs)를 EJS를 사용해 생성합니다.

 

이 과정을 통해 Google OAuth2를 이용한 인증이 Node.js 애플리케이션에 구현됩니다. 사용자는 Google 계정을 통해 앱에 로그인할 수 있으며, 세션은 MongoDB에 저장됩니다.

 

Google OAuth2 인증을 Node.js 프로젝트에 구현하는 과정을 좀 더 세부적인 단계로, 관련 코드를 작성해 보겠습니다. Google 개발자 콘솔에서 자격증명을 생성하는 것부터 시작하여, 실제로 Node.js 애플리케이션에서 사용자 인증을 처리하는 과정까지 포함됩니다.

1. Google API 콘솔에서 프로젝트 생성 및 자격증명 생성

  1. Google API 콘솔 접속: Google Developers Console에 접속하여 로그인합니다.
  2. 새 프로젝트 생성: 콘솔 대시보드에서 '프로젝트 만들기'를 선택하여 새 프로젝트를 생성합니다.
  3. OAuth 클라이언트 ID 생성
    • 생성된 프로젝트를 선택한 후 '자격증명' 메뉴로 이동합니다.
    • '자격증명 만들기' 버튼을 클릭하고 'OAuth 클라이언트 ID'를 선택합니다.
    • 애플리케이션 유형으로 '웹 애플리케이션'을 선택합니다.
    • '승인된 리디렉션 URI' 섹션에 http://localhost:5000/auth/google/callback을 추가합니다.
  4. 자격증명 복사: 생성된 클라이언트 ID와 클라이언트 비밀번호를 복사하여 안전한 곳에 저장합니다.

2. Node.js 프로젝트 설정

  1. 프로젝트 디렉터리 생성: 새 프로젝트용 폴더를 생성하고, 해당 폴더에서 터미널을 엽니다.
  2. NPM 초기화
    npm init -y
    이 명령어는 package.json 파일을 생성하여 프로젝트의 메타데이터와 의존성을 관리합니다.
  3. 의존성 설치: 필요한 Node.js 모듈을 설치합니다.
    npm install express ejs connect-mongo dotenv express-session mongoose passport passport-google-oauth20
    이러한 모듈에는 Express 웹 프레임워크, 템플릿 엔진(EJS), 세션 관리, MongoDB 연동, 환경 변수 관리, Passport 인증 미들웨어 및 Google OAuth2 전략 등이 포함됩니다.

3. 응용 프로그램 코드 작성

  1. 서버 설정 (app.js): 기본 Express 서버를 설정하고, MongoDB에 연결하며, 세션 관리와 Passport 인증을 구성합니다.
    const express = require('express');
    const mongoose = require('mongoose');
    const session = require('express-session');
    const passport = require('passport');
    
    require('./config/passport')(passport); // Passport 설정
    
    const app = express();
    
    // 환경 변수 설정
    require('dotenv').config({ path: './config/config.env' });
    
    // MongoDB 연결
    mongoose.connect(process.env.MONGO_URI, { useNewUrlParser: true, useUnifiedTopology: true });
    
    // EJS 설정
    app.set('view engine', 'ejs');
    
    // Express 세션
    app.use(session({
      secret: 'secret',
      resave: false,
      saveUninitialized: false,
      store: new MongoStore({ mongooseConnection: mongoose.connection })
    }));
    
    // Passport 미들웨어
    app.use(passport.initialize());
    app.use(passport.session());
    
    // 라우트
    app.use('/', require('./routes/index'));
    app.use('/auth', require('./routes/auth'));
    
    const PORT = process.env.PORT || 3000;
    app.listen(PORT, console.log(`Server running on port ${PORT}`));
  2. Passport 설정 (config/passport.js): Passport와 Google OAuth2 전략을 설정하여 사용자 인증을 처리합니다. Google로부터 받은 사용자 정보를 기반으로 사용자를 데이터베이스에서 찾거나 새로운 사용자를 생성합니다.
    const GoogleStrategy = require('passport-google-oauth20').Strategy;
    const mongoose = require('mongoose');
    const User = require('../models/User');
    
    module.exports = function(passport) {
      passport.use(
        new GoogleStrategy({
          clientID: process.env.GOOGLE_CLIENT_ID,
          clientSecret: process.env.GOOGLE_CLIENT_SECRET,
          callbackURL: '/auth/google/callback',
        }, async (accessToken, refreshToken, profile, done) => {
          const newUser = {
            googleId: profile.id,
            displayName: profile.displayName,
            firstName: profile.name.givenName,
            lastName: profile.name.familyName,
            image: profile.photos[0].value,
            email: profile.emails[0].value,
          };
          try {
            let user = await User.findOne({ googleId: profile.id });
            if (user) {
              done(null, user);
            } else {
              user = await User.create(newUser);
              done(null, user);
            }
          } catch (err) {
            console.error(err);
          }
        })
      );
    
      passport.serializeUser((user, done) => {
        done(null, user.id);
      });
    
      passport.deserializeUser((id, done) => {
        User.findById(id, (err, user) => done(err, user));
      });
    };

4. 사용자 모델 설정 (models/User.js)

Google OAuth2에서 반환된 사용자 정보를 저장하기 위한 MongoDB 사용자 스키마를 정의합니다.

const mongoose = require('mongoose');

const UserSchema = new mongoose.Schema({
  googleId: {
    type: String,
    required: true,
  },
  displayName: {
    type: String,
    required: true,
  },
  firstName: {
    type: String,
    required: true,
  },
  lastName: {
    type: String,
    required: true,
  },
  image: {
    type: String,
  },
  email: {
    type: String,
    required: true,
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

module.exports = mongoose.model('User', UserSchema);

5. 라우팅 설정 (routes/auth.js 및 routes/index.js)

  • auth.js: Google OAuth2 인증 프로세스를 처리합니다.
    const express = require('express');
    const passport = require('passport');
    const router = express.Router();
    
    // Google 인증 요청
    router.get('/google', passport.authenticate('google', { scope: ['profile', 'email'] }));
    
    // Google로부터의 콜백 처리
    router.get('/google/callback', 
      passport.authenticate('google', { failureRedirect: '/' }),
      (req, res) => {
        res.redirect('/dashboard');
      }
    );
    
    // 로그아웃 처리
    router.get('/logout', (req, res) => {
      req.logout();
      res.redirect('/');
    });
    
    module.exports = router;
  • index.js: 로그인 페이지와 대시보드 페이지 라우팅을 처리합니다.
    const express = require('express');
    const router = express.Router();
    const { ensureAuth, ensureGuest } = require('../middleware/auth');
    
    // 로그인 페이지
    router.get('/', ensureGuest, (req, res) => {
      res.render('login');
    });
    
    // 대시보드 페이지
    router.get('/dashboard', ensureAuth, (req, res) => {
      res.render('dashboard', { user: req.user });
    });
    
    module.exports = router;

6. 뷰 파일 설정 (views/login.ejs 및 views/dashboard.ejs)

EJS 템플릿을 사용하여 로그인 페이지와 대시보드 페이지를 생성합니다.

  • login.ejs: 로그인 페이지에서 Google 로그인 버튼을 표시합니다.
  • dashboard.ejs: 사용자가 로그인한 후 보게 될 대시보드 페이지를 표시합니다. 사용자의 프로필 정보(이름, 이메일 등)를 표시할 수 있습니다.

 

이 과정을 통해 Node.js 애플리케이션에 Google OAuth2 인증을 성공적으로 구현할 수 있습니다. 사용자는 Google 계정으로 로그인할 수 있으며, 인증 후 대시보드 페이지에서 사용자 정보를 확인할 수 있습니다.

728x90

댓글