구글 개발자 콘솔 설정
구글 인증을 사용하기 위해서는 구글 웹 콘솔에 접속하여 콜백 주소 등의 정보를 입력한 뒤 클라이언트 아이디와 클라이언트 시크릿을 받아야한다. 프로젝트를 생성하고 아이디/시크릿을 받는 과정까지 알아보자.(1) 웹 콘솔에 접속하여 프로젝트를 생성한다.
(2) 생성된 프로젝트 상세 화면으로 이동한 뒤 사용자 인증 정보 메뉴로 이동한다.
(3) 새 클라이언트 ID 만들기 버튼을 클릭하고 승인된 리디렉션 URI를 입력한다. 이것이 패스포트 모듈에서 사용할 콜백 URL이다. 본 테스트는 로컬에서 진행하므로 http://localhost:3000/auth/google/callback
로 입력한다.
(4) 정보를 입력하고 클라이언트 ID 만들기 버튼을 클릭하면 클라이언트 ID와 클라이언트 보안 비밀을 확인할 수 있는데 이것이 각각 clientId
와 clientSecret
이다.
(5) 마지막으로API 메뉴로 들어가 Google + API를 활성화 한다.
모듈 설치
두 가지 모듈이 필요하다.npm install passport passport-google-oauth
폴더구조
사이트에서 제공하는 샘플코드를 볼수도 있지만 익스프레스 코드와 섞여있어 좀 헷갈리다. 별도 파일로 분리했다. 폴더구조를 살펴보자./auth/passport/index.js
: 패스포트 모듈을 등록한다.
/auth/index.js
: 인증 관련 기능을 담당하는 모듈. 여기서는 인증여부를 체크하는 함수 'ensureAuthenticated()`만 구현한다.
/auth/passport/config.json
: 구글 웹콘솔에서 생성한 클라이언트 아이디와 시크릿 정보를 저장한다.
이렇게 auth 폴더에 패스포트를 포함한 인증모듈을 담아둔 뒤, 서버 구동하는 app.js에서 이를 로딩하는 구조로 작성한다. 이를 호출하는 app.js 파일 내부를 살펴보자.
var express = require('express'); var app = express(); // passport settings require('./auth/passport.js').setup(app); // routing app.use('/', require('./routes/index')); module.exports = app;
중간 중간 설명에 필요없는 코드 생략을 유념하고 보자. require('./auth/passport.js').setup(app);
로 패스포트 모듈을 설정한다. 실제 패스포트 모듈 설정을 살펴보자.
'use strict'; var passport = require('passport'); var GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; var session = require('express-session'); var config = require('./config.json'); var GOOGLE_CLIENT_ID = config.google.clientId; var GOOGLE_CLIENT_SECRET = config.google.clientSecret; passport.serializeUser(function(user, done) { done(null, user); }); passport.deserializeUser(function(obj, done) { done(null, obj); }); passport.use(new GoogleStrategy({ clientID: GOOGLE_CLIENT_ID, clientSecret: GOOGLE_CLIENT_SECRET, callbackURL: "http://localhost:3000/auth/google/callback" }, function(accessToken, refreshToken, profile, done) { // asynchronous verification, for effect... process.nextTick(function () { // To keep the example simple, the user's Google profile is returned to // represent the logged-in user. In a typical application, you would want // to associate the Google account with a user record in your database, // and return that user instead. return done(null, profile); }); } )); var setup = function (app) { app.use(session({ secret: 'keyboard cat' })); app.use(passport.initialize()); app.use(passport.session()); app.get('/auth/google', passport.authenticate('google', { scope: ['openid', 'email'] }), function(req, res){ // The request will be redirected to Google for authentication, so this // function will not be called. }); app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/login' }), function(req, res) { console.log(req.query); res.redirect('/'); }); app.get('/logout', function(req, res){ req.logout(); res.redirect('/login'); }); }; exports.setup = setup;
인증페이지인 /login
에 접속하면 사용자는 로그인 링크를 클릭한다.
그럼 /auth/google
로 이동하여 passport.authenticate()
함수를 실행하는데 이때 구글 인증 페이지로 이동한다.
사용자가 승인 하게되면 구글 웹콘솔에서 등록한 콜백URL인 /auth/google/callback
으로 리다이렉팅 한다. 패스포트 모듈을 이를 확인하여 인증정보를 req.user
에 객체형태로 저장한다. 그리고 /
리다이렉트 한다.
/account에는 인증된 사용자만 접근하도록 설정해보자. /auth/index.js
모듈을 호출해서 라우팅 중간에 미들웨어로 끼어 넣으면 된다.
var auth = require('../auth'); router.get('/account', auth.ensureAuthenticated, function(req, res, next) { res.render('account', { title: 'Account', name: req.user.displayName, // 패스포트를 통해 저장된 유저정보 user: JSON.stringify(req.user) }); });
이렇게 설정하면 인증된 요청만 /account
페이지에 접근할수 있게된다.
ensureAuthenicated()
를 구현해 보자.
var ensureAuthenticated = function (req, res, next) { if (req.isAuthenticated()) { return next(); } res.redirect('/login'); }; exports.ensureAuthenticated = ensureAuthenticated;
패스포트 모듈을 통해 리퀘스트 객체는 isAuthenticated()
함수를 호출할수 있는데 이 값이 true를 반환하면 다음 스텝을 진행한다. 그렇지 않을 경우 로그인 페이지로 리다이렉팅 하도록한다.