댓글 검색 목록

[Nodejs] Passport.js를 사용한 Google OAuth 초보자 가이드

페이지 정보

작성자 운영자 작성일 20-06-19 10:04 조회 778 댓글 0

사용자는 새 로그인 계정을 만드는 것보다 편리하고 빠르기 때문에 Google (또는 Facebook, Twitter 등) 계정을 사용하여 웹 응용 프로그램에 로그인하는 경우가 종종 있습니다. 일반적으로 프로세스는 다음과 같습니다.


  1. "Google로 로그인"버튼을 클릭합니다
  2. 앱이 Google 프로필 정보에 액세스 할 수 있는 권한을 부여 할 것인지 묻는 Google 동의 화면으로 리디렉션 됩니다.
  3. "허용"을 클릭하십시오
  4. 실제 응용 프로그램으로 리디렉션

https://dev.to/phyllis_yym/beginner-s-guide-to-google-oauth-with-passport-js-2gh4 


과정은 매우 간단 해 보입니다. 그러나 웹 앱에 대해 Google 로그인을 처음 구현했을 때 훨씬 더 많은 작업이 진행되고 있음을 깨달았습니다. Passport.js라는 인증 미들웨어를 사용하여 구현하기로 결정했습니다.


내가 배운 내용을 바탕으로 이 기사에서는 Passport.js를 사용하여 Express.js 웹 애플리케이션용 Google OAuth를 설정하는 프로세스를 안내합니다. 이 기사에서는 EJS 템플릿 및 리팩토링 프로세스에 대해서는 다루지 않습니다.


전제 조건 


다음이 필요합니다.

  • Express.js 및 Mongo 데이터베이스로 구축 된 기존 앱
  • mongoose의 사용자 모델 클래스로 작성된 Mongo DB의 사용자 콜렉션. 사용자 스키마에 문자열로 googleId를 설정해야 합니다.

이 컬렉션은 사용자의 Google ID를 저장하여 앱이 게시물 (예 : 게시물)과 리소스를 연결하고 로그 아웃 했다가 다시 로그인 한 후 식별 할 수 있도록 합니다.


Passport.js 및 Passport Google OAuth 2.0 전략이 ​​설치되었습니다. 이들이 설치되어 있는지 확인하려면 터미널에서 다음 명령을 실행하십시오.


cat package.json | grep passport 


설치 한 결과는 다음과 유사합니다.


"passport": "^0.4.1",
"passport-google-oauth20": "^2.0.0"


결과가 비어 있으면 터미널에서 다음 명령을 실행하여 설치하십시오.


npm install passport passport-google-oauth20 --save


OAuth 흐름 


다음 순서도는 개발자의 관점에서 OAuth 플로우의 큰 그림을 보여줍니다.


Alt Text 


우리는 이 단계들을 잠시 후에 논의 할 것입니다. 시작하려면 먼저 Passport를 설정하고 전략을 구성해야 합니다.


준비 단계 1 : Passport 설정 


Passport를 설정하려면 Passport와 Passport-Google-OAuth2.0을 모두 요구하고 Passport에 새로운 Google 전략 인스턴스를 사용하도록 지시 해야 합니다.

const passport = require("passport");
const GoogleStrategy = require("passport-google-oauth20").Strategy;

passport.use(new GoogleStrategy());


준비 2 단계 : Google에서 자격 증명 얻기 


Google이 API와 상호 작용하는 애플리케이션의 Passport를 식별하려면 Google Developers Console에서 clientID 및 clientSecret을 얻어야 합니다. 단계는 이 안내서를 참조하십시오.


또한 "Authorized JavaScript Origins"및 "Authorized redirect URI"를 작성하라는 메시지가 표시됩니다. 

승인 된 JavaScript는 앱이 수신하는 로컬 호스트 URL이어야 합니다 (예 : http : // localhost : 3000). 승인 된 리디렉션 URI는 사용자에게 앱에 대한 권한을 부여한 후 사용자에게 전송되는 경로입니다.

이 예에서는 http : // localhost : 3000 / auth / google / redirect로 설정했습니다.


준비 단계 3 : 키 보안 


보안을 위해 Google 자격 증명을 Google 전략에 연결하기 전에 config 폴더의 keys.js 파일에 저장해야 합니다. 이 파일을 gitignore에 추가하여 Git에 커밋되지 않도록 해야 합니다.


module.exports = {
  mongodb:{
    dbURI: "your_mongo_atlas_SRV_address"
  },
  google:{
    clientID:"your_client_ID",
    clientSecret:"your_client_secret"
  }
};



준비 단계 4 : Google 전략 구성 


다음 단계는 방금 app.js에서 생성 한 키 파일과 Google 개발자 콘솔에서 방금 만든 Google 자격 증명 및 승인 된 리디렉션 URI에 연결하여 Google 전략을 구성하는 것입니다.


지금은 두 번째 인수 인 accessToken에 대해 걱정하지 마십시오. 아래 3 단계 구현에서 설명하겠습니다.


const passport = require("passport");
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const keys = require("./config/keys");

passport.use(
  new GoogleStrategy(
    {
      clientID: keys.google.clientID,
      clientSecret: keys.google.clientSecret,
      callbackURL: "/auth/google/redirect"
    },
    accessToken => {
      console.log("access token: ", accessToken);
    }
  )
);


이제 기본 OAuth 흐름을 다시 살펴 보겠습니다. 흐름을 구현하는 방법을 보여주는 코드 스니펫을 포함 시켰습니다.


구현 단계 1 : 사용자가 "Google에 로그인"을 클릭하면 


그런 다음 앱은 Passport를 제어하여 인증을 처리하기 위해 Google과 통신합니다. 사용자는 Google 페이지로 이동하여 사용자의 허가를 요청합니다.


Passport는 이미 이전에 설정되었으므로 OAuth 플로우를 시작합니다.


app.get("/auth/google", passport.authenticate("google", {
    scope: ["profile", "email"]
  }));


범위에 대한 간단한 설명 : 앱에서 액세스하려는 사용자의 Google 정보를 지정합니다. 이 예에서는 사용자의 Google 프로필 및 이메일 주소에 액세스해야 하므로 범위 옆에 프로필 및 이메일을 넣습니다. 전체 범위 목록은 여기에서 찾을 수 있습니다.


구현 단계 2 : 사용자가 동의 화면에서 "허용"을 클릭 한 후 


페이지가 Google Developers Console에서 설정 한 리디렉션 URI로 리디렉션됩니다. 

URI에는 Google의 코드도 포함되어 있으며 Passport에서 사용자 정보를 요청하는 데 사용됩니다.


app.get("/auth/google/redirect",passport.authenticate('google'));



구현 단계 3 : Google이 사용자의 프로필 정보로 답장하는 경우 


서버는 여권 콜백 기능을 실행하여 앱 데이터베이스에서 사용자를 조회하거나 생성합니다. 사용자가 로그인 한 횟수에 관계없이 하나의 사용자 레코드 만 원하므로 먼저 앱에서 데이터베이스에 지정된 Google 프로필 ID를 가진 이 사용자가 있는지 확인해야 합니다. 대답이 예이면 데이터베이스에서 사용자 작성을 건너 뛸 수 있습니다. 그러나 그렇지 않은 경우 새 사용자를 만들어야 합니다.


이를 위해 여권 콜백 기능을 다음과 같이 수정해야 합니다. 또한 몽구스와 데이터베이스의 사용자 모델이 필요합니다.


const passport = require('passport');
const GoogleStrategy = require('passport-google-oauth20').Strategy;
const mongoose = require('mongoose');
const keys = require('./config/keys');
const User = require("your_user_model_file_path");

passport.use(
  new GoogleStrategy({
      clientID: keys.google.clientID,
      clientSecret: keys.google.clientSecret,
      callbackURL: '/auth/google/redirect'
  }, (accessToken, refreshToken, profile, done) => {
      // passport callback function
      //check if user already exists in our db with the given profile ID
      User.findOne({googleId: profile.id}).then((currentUser)=>{
        if(currentUser){
          //if we already have a record with the given profile ID
          done(null, currentUser);
        } else{
             //if not, create a new user 
            new User({
              googleId: profile.id,
            }).save().then((newUser) =>{
              done(null, newUser);
            });
         } 
      })
    })
);


콜백 함수의 인수에 대한 간단한 설명 :

  • accessToken : 액세스 토큰은 응용 프로그램이 사용자 대신 API 요청을 하는 데 사용하는 것입니다. 이 예에서는 액세스 토큰을 사용하지 않습니다.
  • refreshToken : 액세스 토큰은 일반적으로 수명이 제한되어 있습니다. 앱이 만료되고 앱이 보호 된 리소스에 액세스하려는 경우 새로 고침 토큰을 사용하여 앱이 사용자에게 묻지 않고 새 액세스 토큰을 얻을 수 있습니다. 또한 이 예에서는 새로 고침 토큰을 사용할 필요가 없습니다.
  • done 함수 : 이것은 우리가 사용자를 찾거나 생성을 완료했음을 여권에 알리기 위해 호출되며 이제 인증 흐름을 진행해야 합니다.
  • null : 여권에 문제가 없고 오류가 없음을 알려주는 오류 객체.

구현 단계 4 : Passport의 serializeUser 함수 호출 


즉, Passport는 식별 토큰을 생성하여 쿠키 안에 넣고 사용자의 브라우저로 보냅니다. 코드의 사용자는 방금 데이터베이스에서 조회 또는 생성 한 사용자 모델 인스턴스를 나타내며 user.id는 Google 프로필 ID 대신 Mongo에서 할당 한 ID입니다. 

사용자가 Google 이외의 Facebook 또는 Twitter 계정으로 앱에 로그인 할 수 있는 시나리오를 상상해보십시오. 

즉, Google ID없이 로그인 할 수 있습니다. 그래서 serializeUser 함수에서 Google ID 대신 user.id를 사용합니다.

passport.serializeUser((user, done) => {
  done(null, user.id);
});


구현 단계 5 : 나중에 사용자는 브라우저에서 앱의 일부 리소스를 요구합니다 (예 : 게시물 요청). 


쿠키는 서버로 전송 된 요청에 자동으로 추가됩니다. 그런 다음 서버는 쿠키에서 식별 토큰을 가져 와서 deserializeUser 함수로 전달하여 사용자로 전환합니다. 그런 다음 Passport는 사용자가 이미 인증되었음을 확인하고 요청 된 게시물을 사용자의 브라우저로 보내도록 서버에 지시합니다.


passport.deserializeUser((id, done) => {
  User.findById(id).then(user => {
    done(null, user);
  });
});


구현 단계 6 : Passport가 쿠키를 사용하여 인증을 처리하도록 지시합니다. 


먼저 터미널에서 다음 명령을 실행하여 쿠키 세션을 설치합시다.


npm install cookie-session --save


그런 다음 app.js 파일에 쿠키 세션이 필요합니다.


const cookieSession = require("cookie-session");


다음으로 쿠키를 암호화하고 구성 폴더의 keys.js 파일에 쿠키를 저장하는 키를 만들어 보겠습니다. 키는 임의의 문자 일 수 있습니다.


module.exports = {
   mongodb:{
    dbURI: "your_mongo_atlas_SRV_address"
  },
  google:{
    clientID:"your_client_ID",
    clientSecret:"your_client_secret"
  },
  session:{
    cookieKey:"cookie_key_set_up_by_you"
  }
};



이 단계 후에 app.js 파일에 다음을 추가하여 앱이 쿠키 세션을 사용하도록 하고 여권에 쿠키 세션을 사용하여 인증을 처리하도록 지시하십시오. maxAge는 쿠키 지속 시간의 밀리 초를 나타냅니다.


app.use(cookieSession({
  // milliseconds of a day
  maxAge: 24*60*60*1000,
  keys:[keys.session.cookieKey]
}));

app.use(passport.initialize());
app.use(passport.session());


구현 단계 7 : 작동하는지 테스트 !! 


deserializeUser 함수에서 얻은 사용자 모델 인스턴스가 req.user로 req 객체에 추가되었습니다. 

전체 OAuth가 작동하는지 테스트하기 위해 req.user를 사용할 수 있습니다. 먼저 Google에서 콜백 경로를 수정하여 다음으로 리디렉션 할 수 있습니다.


router.get("auth/google/redirect",passport.authenticate("google"),(req,res)=>{
  res.send(req.user);
  res.send("you reached the redirect URI");
});


그런 다음 로그 아웃 경로를 설정했습니다.


app.get("/auth/logout", (req, res) => {
    req.logout();
    res.send(req.user);
  });



테스트하려면 서버를 다시 시작하고 http : // localhost : 3000 / auth / google로 이동하십시오. 작동하면 Google 동의 화면으로 이동합니다. "허용"을 클릭하면 사용자 모델에 설정 한 정보 (예 : 적어도 Google ID)와 "리디렉션 URI에 도달했습니다"라는 메시지가 포함 된 req.user 객체를 볼 수 있습니다.

로그 아웃 기능이 작동하는지 확인하려면 http : // localhost : 3000 / auth / logout으로 이동하십시오. req.user 객체가 표시되지 않으면 쿠키가 삭제되어 로그 아웃 한 것입니다.


??? 축하합니다! 우리는 해냈다! 웹 응용 프로그램에서 Passport.js를 사용하여 Google OAuth를 성공적으로 설정했습니다.


참고 문헌 :



댓글목록 0

등록된 댓글이 없습니다.

웹학교 로고

온라인 코딩학교

코리아뉴스 2001 - , All right reserved.