반응형

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

 

 

 

반응형
반응형


Socket IO를 이용한 정말 간단한 채팅 프로그램이며, express를 사용한다.

기초만 쓴것이기 때문에 정말로 간단하다.


전체 코드 :  https://github.com/wonkwangyeon/Real_Simple_SocketIO_Chat


1. 프로젝트를 하나 만들고 아래의 명령어를 입력한다.


npm init
npm install express --save
npm install socket.io --save


2. 입력후 app.js라는 파일과 client.html라는 파일을 만든다.




3. app.js 파일에 들어가 아래와 같이 입력한다. (위 github에서 복사 가능)



5번째 라인 :  서버를 오픈한다. 또한 Socket.IO 홈페이지의 레퍼런스에서 app.listen으로 서버를 열지마라고 주의한다.

10번째 라인 : localhost:3000 으로 들어가면 바로 client.html을 열기 위함이다.

15번째 라인 : socket io 에 접속한다.

16번째 라인 : 클라이언트에서 들어오는 메세지를 받은후

18번째 라인 : 이 메세지를 접속한 모든 클라이언트에게 보낸다.


간단하다 on이 메세지를 받는 함수, emit이 메세지를 보내는 함수이다.  앞의 'receive'라는 것을 통해 어디로 보내고 어디로 받는지 정할 수 있다. 

클라이언트 부분을 보면 간단하게 이해가 된다.


4. client.html



20~32번째 라인 : 메세지를 받고 전송하는 간단한 입력 폼 전체 소스를 보면 20번째 위에는 아주 간단한 css가 설정되어있다.

33번째 라인 : 핵심. 이것을 통해 socket.io를 사용할 수 있다.

35번째 라인 : 서버에서 오픈한 socket 서버에 접속한다.

37번째 라인 : 버튼을 누르면 실행하는 이벤트이다.

38번째 라인 : 위에 설명하였듯이 emit이 메세지를 보내는 함수 이다. 그리고 'receive'라는 서버에서 설정한 이름을 통해 그곳으로 메세지를 보낸다.

39번째 라인 : 메세지를 보냈으면 현재 입력되어 있는 메세지를 초기화하는 것.

41번째 라인 : 위에 설명하였든이 on이 메세지를 받는 함수이다. 'client_receive'라는 이름이라고 설정하였고 서버에서

 emit을 'client_receive'라고 설정하여 보낸다.

42번째 라인 : 받은 내용을 22번째 라인의 textarea에 설정한다.


5. 결과


node app.js 를 통해 실행하고

localhost:3000로 접속한다.



기본적인 함수를 익히고 이를 통해 정말로 간단한 채팅프로그램을 만들어보았다.


전체 코드 :  https://github.com/wonkwangyeon/Real_Simple_SocketIO_Chat


참고 :  https://socket.io/docs/#What-Socket-IO-is

반응형
반응형

Spring boot에서 AWS Elastic Beanstalk 사용시 .ebextensions 사용하는 방법이다.

Elastic Beanstalk 사용시 배포방법이 war파일 배포방법과 jar파일 배포방법이 있는데

이 두개는 .ebextensions 사용시 기본적인 사용법은 같으나 배포시 차이점이 있다.



1. 2018/10/26 - [Develop/Spring Boot] - Spring Boot AWS Elastic BeanStalk을 이용한 배포

2. 2019/02/12 - [Develop/Spring Boot] - Spring boot ElasticBeanstalk 환경변수설정시 주의사항



1.  기본 사용방법으로는 .ebextensions 란 폴더를 프로젝트 최상위에 만든다. 




2. 만들었으면 이제 서버에 적용하고 싶은 값들을 .config 확장자로 만들어 .ebextensions의 폴더에 넣으면 된다.

기본적으로 적용하고싶은 파일들의 순서는 알파벳순서라서, 보통 00-이름.config, 01-이름2.config 이렇게 이름을 짓는다.


[Directory구조 예시]

Project

--.ebextensions 

-- 00-이름.config

-- 01-이름2.config


3. 이제 nginx설정하는 방법이다. (이것이 필요 없다면 바로 4번의 배포 방법으로 가시면 됩니다.)

아래의 사진처럼 폴더를 생성한다.


3-1 . 먼저 nginx 설정을 변경하고싶다면 nginx의 전체 속성을 일단 복사해서 가져온 뒤

nginx.conf라는 파일을 생성 후 복사한 전체 내용을 ngnix.conf에 붙여넣고 변경하고 싶은 내용을 추가하면 된다. 

위 사진처럼 nginx 폴더(conf.d폴더가아님) 바로 아래에 nginx.conf 파일을 넣는다. 이렇게 되면 nginx 의 전체설정을 서버에 완전히 쓰게 된다.


3-2. nginx 전체 설정 가져오기가 번거롭다면 위 사진처럼 conf.d 폴더와 그리고 아래에 elasticbeanstalk이라는 폴더를 생성한다.

conf.d폴더아래에 만약 .conf 파일을 생성한다면 이 내용은 nginx.conf 전체 속성의 http 단에 들어가고

elasticbeanstalk 폴더 아래에 만약 .conf 파일을 생성한다면 이 내용은 nginx.conf 전체 속성의 http 단의 sever 단에 들어간다


이게 무슨말이냐면 아래의 사진처럼 conf.d 폴더에 생성한 .conf 파일의 내용은 검정색 선 안에 들어가고

elasticbeanstalk 폴더 아래에 생성한 .conf 파일의 내용은 빨간색 선 안에 들어간다.



이런식으로 nginx 설정을 변경한다.


4. 배포는 war파일 배포와 jar파일 배포시 차이가 있다. 일단 공통적으로 zip 을 해주어야 한다.



4-1. war 파일은 .ebextensions 폴더와 함께 zip 파일로 만든후 이를 Elastic Beanstalk에 올리면 ebextensions 에서 설정한 값이 적용된다.



[.zip 파일 directory 예시]

.zip

-- .ebextensions 

-- .war


4-2. jar파일은 zip파일로 만들고 배포하면 설정이 먹히지 않는다. 그렇기 때문에 Procfile 이라는 것을 사용해야 한다.

Procfile을 말 그대로 Procfile이라고 프로젝트 최상위 경로에 생성한다 


[Directory구조 예시]

Project

--.ebextensions 

-- 00-이름.config

-- 01-이름2.config

--Procfile


생성 후 Procfile 내용안에 아래와 같이 작성한다.


web: java -jar jar파일경로/파일이름.jar


작성하였으면 이제 .ebextensions 폴더와 .jar파일 Procfile을 zip 파일로 압축한다.


[.zip 파일 directory 예시]

.zip

-- .ebextensions 

-- .jar

-- Procfile


그리고 이를 Elastic Beanstalk에 올리면 ebextensions 에서 설정한 값이 적용된다.



(어차피 zip파일로 압축할거면 굳이 root 폴더에 생성해야하는 이유가 무엇인지 궁금하다.

build 시 자동으로 zip 파일로 압축하는 방법이 있다고 하던데 알아봐야겠다.)



참고 :  https://docs.aws.amazon.com/ko_kr/elasticbeanstalk/latest/dg/create_deploy_Java.html

반응형

+ Recent posts