Node.js에서 google oauth 인증하는 방법이다.
이전에는 passport를 사용하지 않는 방법을 이용하여 JWT와 함께 쿠키로 로그인 인증처리를 했다면,
이번엔 세션을 이용하여 passport를 이용하는 방법이다.
기본적으로 https://console.cloud.google.com 에서 프로젝트를 생성했다는 가정하에 작성한다.
1. passport를 이용하지 않은 google oauth 인증 후 jwt 사용
2019/01/07 - [Develop/Node.js] - [Node.js] google oauth 인증 (구글 로그인)
1. 적당한 프로젝트를 생성 후 아래와 같은 명령어를 입력한다.
npm init npm install express --save npm install express-session --save npm install session-file-store --save npm install passport --save npm install passport-google-oauth
express 를 사용할 것이기 때문에 express를 설치한다. 그리고 passport는 기본적으로 session을 이용하기 때문에 express-session도 설치하고
session 저장소를 파일로 처리할 것이기 때문에 session-file-store 를 설치한다.
그리고 사용할 passport와 passport의 전략중 하나인 passport-google-oauth를 설치한다.
※아래엔 express-session에서 파일로 세션을 저장하는 것 말고 데이터베이스 등을 사용하는 방법을 확인 할 수 있다.
https://www.npmjs.com/package/express-session
2. express를 설정하고 다음 session을 설정한다.
먼저 server.js 파일을 생성하고 아래와 같이 작성한다.
https://www.npmjs.com/package/express-session 에 접속해서 기본적인express-session을 사용하기 위해
아래 주석 //1의 미들웨어를 설정한다.
주석 //2번은 localhost:3000으로 접속할 때 나오는 기본 화면이다.
주석 //3은 express를 통해 3000포트를 이용하여 서버를오픈한다.
var express = require('express'); var session = require('express-session') var FileStore = require('session-file-store')(session) var app = express(); app.use(session({ // 1 secret: 'keyboardcat', resave: false, saveUninitialized: true, store: new FileStore() })) app.get('/', function (req, res, next) { //2 console.log('홈') }) app.listen(3000, function () { //3 console.log('Example app listening on port 3000!'); });
3. Google Cloud Platform 에서 Json 파일을 다운받고, config 폴더를 만든 뒤 다운받은 json 파일을 config폴더에 넣는다.
사진 맨 오른쪽 하단에 빨간줄로 표시한 아이콘을 클릭하여 json파일을 다운받는다.
다운받은 json 파일엔 기본적으로 아래와같이 나와있다.
이 파일을 아래 처럼 넣는다. 이유는 그냥 가져다 쓰는 것보다 저렇게 가져오는 것이 조금이나마 안전하기 때문.
4. passport를 설정한다.
4-1. passport 전략 중 하나인 우리가 사용할 passport-google-oauth를 사용한다.
server.js에 추가한다.
//1 아래와 같이 passport를 가져오고
//2 passport를 초기화시킨다.
//3 session을 이용하기 때문에 추가한다.
//4 실질적으로 로그인할 수 있는 경로와 scope이다. scope에서는 email이나 기타 정보를 가져 올 수도 있다.
//5 메인페이지에 4번에서 설명한 실질적으로 로그인하는 경로를 설정한다.
var passport = require('passport'), GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; //1 app.use(passport.initialize()); //2 app.use(passport.session()); //3 app.get('/auth/google', //4 passport.authenticate('google', { scope: 'https://www.googleapis.com/auth/plus.login' })) app.get('/', function (req, res, next) { //5 var html = ` login with google` res.send(html) })
위와 같이 설정하고 'node server.js' 명령어를 통해 실행해서 접속하면 아래와 같은 화면이 뜬다.
4-2. 구글 로그인을 해서 정보를 얻어올 로직과 세션에 담을 로직을 구현한다.
//1 은 로그인했을 시 얻어오는 정보가아니라 그냥 임의로 넣었다 사실 이렇게 하는 것은 아니고 바로 아래에서 다시 설명할 예정
//2 로그인 성공하고 로그인 성공했을 때 가져오는 user.id를 세션에 설정한다.
//3 로그인이 성공했으면 페이지를 항상 새로 불러올 때마다 불러오는 것이다.
그리고 세션에서 serialize에서 설정한 user id를 불러온 후 user 정보를 보여주는 것이다.
//4 아까 json파일에서 client_id와 secret, redirect uri를 불러온다.
//5 로그인이 성공했을 경우 scope를 설정한대로 구글측에서 profile 정보를 가져온다.
//5를 통해 로그인이 성공하면 scope에서 설정한 대로 profile에서 정보를 가져오는데
성공적으로 가져왔으면 이를 done을 통해 정보를 설정하면
serializeUser로 가서 설정하고
설정된 값이 deserializeUser에서 불러온다.
다시말하자면 원래 var loginData를 설정하는 것이아니라
//5에서 일단 로그인 인증 처리를 한다 -> 데이터베이스에 넣거나, 데이터베이스에 있는 값을 가져와 회원이 맞는지 비교를 한다든지
이런 기본적인 로그인 처리를 설정하고. 이것이 통과된다면 done을 통해 정보를 return하면
//2의 serializeUser가 호출되는데 여기서 user.id ( 꼭 id가아니라 email이면 user.email도 가능) 을 session에 설정한다.
//3 그럼 페이지가 항상 호출될 때마다 deserializeUser가 호출 되는데 deserializeUser의 id를 통해
데이터베이스에 접속해서 이 아이디가 로그인이 된 상태라든지 이런 것들을 확인할 수 있다.
(너무 이상하게 설명한 것 같은데 이해가 되지않는다면 댓글에 적어주시면 감사하겠습니다.)
var config = require('./config/google.json')
var loginData = { //1 id : 'test', pw : '1' } passport.serializeUser(function(user, done) { //2 console.log('serialize', user); done(null, user.id); }); passport.deserializeUser(function(id, done) { //3 console.log('deserialize', id); done(null, loginData) }); passport.use(new GoogleStrategy({ //4 clientID: config.web.client_id, clientSecret: config.web.client_secret, callbackURL: config.web.redirect_uris[0] }, function(accessToken, refreshToken, profile, done) { //5 return done(null, loginData) } ));
4-3. 로그인이 정상 처리 되어 callback될 주소를 설정한다.
//1 Json파일의 redircet_uri를 설정한다 기본적으로 /auth/google/callback 이다.
//2 로그인이 정상 처리 된다면 //3의 redirect('/') 홈으로 가고
실패하면 /bye로 보냈다. 이것은 다시 로그인 하는 곳으로 보낼 수 있고 처리하는 것은 개발자 마음이다.
//4 이것을 설정하지 않으면 세션이 스토어에 저장하는 데 오래걸릴 경우 리다이렉트를 시킬 수 있기 때문에 이를 방지하여
세션이 스토어에 저장이 완료되면 리다이렉트를 시키는 코드이다.
//5 로그인 실패시 보내는 주소이다.
//6 위에서 설정한 app.use(passport.session()) 미들웨어를 통해 req에서 user를 호출 할 수 있다.
이것을 통해 deserilize가 호출 되는 것을 확인할 수 있다.
app.get('/auth/google/callback', //1 passport.authenticate('google', { //2 failureRedirect: '/bye' }), function(req, res) { //3 req.session.save(function(){ //4 res.redirect('/'); }) }); app.get('/bye', function (req, res, next) { //5 res.send('login failed') }) app.get('/', function (req, res, next) { console.log(req.user) //6 var html = ` login with google` res.send(html) })
5. 결과
node server.js 명령어를 통해 실행 후
login with google을 클릭하여 로그인을 하게되면
로그인이 성공하면 serialize를 호출하고
페이지를 새로고침할 때마다 deserialize가 호출 되는 것을 볼 수 있다.
6. 전체 코드
var express = require('express'); var session = require('express-session') var FileStore = require('session-file-store')(session) var config = require('./config/google.json'); var app = express(); app.use(session({ secret: 'keyboardcat', resave: false, saveUninitialized: true, store: new FileStore() })) var loginData = { id : 'test', pw : '1' } var passport = require('passport'), GoogleStrategy = require('passport-google-oauth').OAuth2Strategy; app.use(passport.initialize()); app.use(passport.session()); passport.serializeUser(function(user, done) { console.log('serialize', user); done(null, user.id); }); passport.deserializeUser(function(id, done) { console.log('deserialize', id); done(null, loginData) }); passport.use(new GoogleStrategy({ clientID: config.web.client_id, clientSecret: config.web.client_secret, callbackURL: config.web.redirect_uris[0] }, function(accessToken, refreshToken, profile, done) { return done(null, loginData) } )); app.get('/auth/google', passport.authenticate('google', { scope: 'https://www.googleapis.com/auth/plus.login' })) app.get('/auth/google/callback', passport.authenticate('google', { failureRedirect: '/bye' }), function(req, res) { req.session.save(function(){ res.redirect('/'); }) }); app.get('/', function (req, res, next) { console.log(req.user) var html = ` login with google` res.send(html) }) app.get('/bye', function (req, res, next) { res.send('login failed') }) app.listen(3000, function () { console.log('Example app listening on port 3000!'); });
참고 :
https://www.npmjs.com/package/express-session
'Develop > Node.js' 카테고리의 다른 글
Npm, Yarn Nexus Repository 설정 (0) | 2022.07.06 |
---|---|
[Node.js] Node.js Slack WebHooks (슬랙 웹훅) (1) | 2019.05.03 |
Socket IO를 이용한 정말 간단한 채팅 프로그램 (0) | 2019.02.21 |
[Node.js] google oauth 인증 (구글 로그인) (0) | 2019.01.07 |
[Node.js] JWT Token 생성 및 검증 (0) | 2019.01.06 |