Node.js에서 google oauth 인증하는 방법이다. 

passport를 사용하는 방법이 있지만 passport는 사용해보니 무조건 session을 이용해야 했다.(아닐 수도 있음.)

이 글은 passport를 사용하지 않는 방법이다.


1.passport를 사용한 google oauth 인증

2019/03/11 - [Develop/Node.js] - [Node.js] google oatuh passport




프로젝트는 아래의 글을 사용했다. (순수 express 설치하는 글임)

2019/01/06 - [Develop/Node.js] - [Node.js] Express 설치(Windows)


1. googleapis 를 설치한다

npm install googleapis --save

2. google cloud console에서 .json파일을 받는다.


받은 파일을 아래와 같이 config 폴더에 넣어 google.json으로 변경한다.




3. server.js 파일에 아래와 같이 추가한다.


install 한 googleapis를 불러오고 .json 파일에서 client_id와 secret, redirect_uri를 불러온다.

const { google } = require('googleapis');
var googleClient = require('./config/google.json');

const googleConfig = {
  clientId: googleClient.web.client_id,
  clientSecret: googleClient.web.client_secret,
  redirect: googleClient.web.redirect_uris[0]
};

사용할 scopes를 입력하고, OAuth2.0에 실질적으로 연결할 정보들을 다시 연결한다. 

scope는 아래 API라이브러리에서 본인이 사용하고 싶은 api를 보고 가져오면된다.

여기서는 google api + 를 이용할 예정이다.



const scopes = [
  'https://www.googleapis.com/auth/plus.me'
];


const oauth2Client = new google.auth.OAuth2(
  googleConfig.clientId,
  googleConfig.clientSecret,
  googleConfig.redirect
);

로그인 url을 받아오기 위한 정보를 입력한다. 

access_type에는 online과 offline이 있는데 offline으로 해야 제일 처음 로그인 했을 때 refresh_token을 받아온다.

(refresh_token은 항상 제일 처음 로그인할 때 가져온다 그러므로 다시 가져오고 싶으면 https://myaccount.google.com/permissions 에서 액세스된 어플리케이션을 해제해야 한다.)


scope는 위에 입력한 scope들을 가져온다. 지금처럼 scope하나만 가져올경우 

scope : 'https://www.googleapis.com/auth/plus.me' 바로 적어도 된다. 하지만 여러 scope를 가져올 경우 위에 처럼 배열을 하나 만들어

여러 scope들을 사용할 수 있다.

그리고 google+ api를 사용하기 위해 google+ api에 대한 정보를 입력한다.

const url = oauth2Client.generateAuthUrl({
  
  access_type: 'offline',

  
  scope: scopes
});

function getGooglePlusApi(auth) {
  return google.plus({ version: 'v1', auth });
}

실질적으로 로그인해서 정보를 불러올 코드를 작성한다. 

간단하게 리프레시토큰, 액세스토큰, displayName과 id를 얻어와본다.

async function googleLogin(code) {
  const { tokens } = await oauth2Client.getToken(code);
  oauth2Client.setCredentials(tokens);
  oauth2Client.on('tokens', (token) => {
    if(tokens.refresh_token){
      console.log("리프레시 토큰 :", tokens.refresh_token);
    }
    console.log("액세스 토큰:", tokens.access_token);
  });
  const plus = getGooglePlusApi(oauth2Client);
  const res = await plus.people.get({ userId: 'me' });
  console.log(`Hello ${res.data.displayName}! ${res.data.id}`);
  return res.data.displayName;
}

4. login할 주소와 로그인이 되었을 경우 실행될 callback 주소를 작성한다.

로그인할 주소는 아까 로그인 할 url 받아올 url변수의 정보를 redirect 시키고

callback 주소는 google.json의 redirect 주소를 적으면 된다.

그리고 로그인이 성공했을 경우 돌아올 redircet주소를 적는다. 


app.get('/login', function (req, res) {
  res.redirect(url);
});

app.get("/auth/google/callback", async function (req, res) {

  const displayName = await googleLogin(req.query.code);
  console.log(displayName);

  res.redirect("http://localhost:3000");
});

5. 실행한다.



localhost:3000/login 으로 들어간다.




localhost:3000/login 으로 들어가면 아까 url 을 통해 아래의 사진으로 연결된다.


이제 아이디를 쳐서 로그인하면 아까 입력한 scope에 따라 권한을 받게되고 이후 성공하면 redirect 시킨 home으로 돌아온다.



그리고 console을 확인해보면 현재 액세스토큰과 displayName, id가 나왔다.

리프레시토큰은 전에 로그인을 한번해서(시험 삼아 한번 해봄). 안나왔지만, 제일 처음 로그인을 했다면 리프레시토큰 또한 나올 것이다.

(리프레시토큰은 제일 처음 한번만 발급된다.)



6. 전체코드



var express = require('express');
var app = express();

const { google } = require('googleapis');
var googleClient = require('./config/google.json');

const googleConfig = {
  clientId: googleClient.web.client_id,
  clientSecret: googleClient.web.client_secret,
  redirect: googleClient.web.redirect_uris[0]
};

const scopes = [
  'https://www.googleapis.com/auth/plus.me'
];

const oauth2Client = new google.auth.OAuth2(
  googleConfig.clientId,
  googleConfig.clientSecret,
  googleConfig.redirect
);

const url = oauth2Client.generateAuthUrl({

  access_type: 'offline',

  scope: scopes
});

function getGooglePlusApi(auth) {
  return google.plus({ version: 'v1', auth });
}

async function googleLogin(code) {
  const { tokens } = await oauth2Client.getToken(code);
  oauth2Client.setCredentials(tokens);
  oauth2Client.on('tokens', (tokens) => {
    if(tokens.refresh_token){
      console.log("리프레시 토큰 :", tokens.refresh_token);
    }
    console.log("액세스 토큰:", tokens.access_token);
  });
  const plus = getGooglePlusApi(oauth2Client);
  const res = await plus.people.get({ userId: 'me' });
  console.log(`Hello ${res.data.displayName}! ${res.data.id}`);
  return res.data.displayName;
}

app.get('/login', function (req, res) {
  res.redirect(url);
});

app.get("/auth/google/callback", async function (req, res) {

  const displayName = await googleLogin(req.query.code);
  console.log(displayName);

  res.redirect("http://localhost:3000");
});



app.get('/', function (req, res) {
  res.send('Hello World!');
  console.log("로그인 해서 홈으로 돌아옴");

});

app.listen(3000, function () {
  console.log('Example app listening on port 3000!');
});




참고 : 


https://www.npmjs.com/package/googleapis


+ Recent posts