우리가 A라는 사이트에 로그인 할 때 구글을 이용해 로그인 하시겠습니까?
버튼을 눌러서 구글을 통해 A사이트를 로그인 할 수 있게 만드는 기술임
User입장에서 매 사이트마다 id, password를 만들어도 되지 않으니 편하기도 하고
App client에서 OAuth방식을 이용해서 로그인 할 경우 App client에 id, password가 노출될 일도 없어서 보안 상으로도 이점이 있는 기술임
(사전작업) client app은 resource server로 부터 id와 secret password를 가져온다(resource server입장에서 client에게 라이센스를 부과하는 과정과 같음)
2. user(resource owner)가 client app에 본인의 id와 password를 맡기고 client는 server에 resource owner의 정보를 요청한다
(사전작업) client app은 resource server로 부터 id와 secret password를 가져온다(client입장에서 resource server에게 라이센스를 부과하는 과정과 같음)
1. user는 client app페이지로 로그인을 시도한다
2. client app은 user interface화면에 '구글로 로그인 하시겠습니까?'라는 화면을 띄운다
3. '동의'버튼을 누르면 user는 client app에서 자동적으로 구글로 접속된다(user가 직접 구글로 접속하는 것과 같음)
4. 구글은 client app에게 user가 동의했음을 authorization code를 전달함으로써 알려준다
5. client app은 본인이 원래 들고 있던 라이센스(id, scret password)와 구글로부터 전달받은 code(user가 정보제공에 동의했음을 증명하는 물건)를 구글로 보내준다
5-1. 구글은 id, secret password, code를 합쳐서 이 client app이 라이센스를 받은 안전한 사용자인지, user의 정보제공은 받았는지 판단한다
5-2. 구글은 client app에게 access token을 발행한다 (만약 client app으로부터 받은 모든 데이터가 유효하다면)
6. client app은 전달받은 access token을 가지고 구글에 접속한다
7. 구글은 client app에게 요청한 data를 제공한다
8. client app은 user에게 뽑아온 데이터를 제공한다(raw data를 전달하지 않고 가공된 데이터를 전달하는 것도 가능)
https://www.youtube.com/watch?v=PIlP_YX5HK8
Refresh Token Grant Type을 통해 재발급 받아야 함
require('dotenv').config();
const clientID = process.env.GITHUB_CLIENT_ID;
const clientSecret = process.env.GITHUB_CLIENT_SECRET;
const axios = require('axios');
module.exports = (req, res) => {
console.log(req.body);
//우리는 client app으로써 github이라는 Authorization Server에 clientId, clientSecret, code를 post함으로써 access token을 발급받고 싶은 상황이다
axios({
method: 'post',
url: `https://github.com/login/oauth/access_token`,
headers: {
"Content-Type": "application/json", //Content-Type을 데이터를 어떤 형태로 보내겠다고 말하는 부분이다 json으로 보내겠다고 했다
accept: 'application/json', //accpet는 데이터를 어떤 형태로 받겠다고 말하는 부분이다 json으로 받겠다고 했다
},
data: {
client_id: clientID,
client_secret: clientSecret,
code: req.body.authorizationCode
}
})
.then((data) => {
//console.log(data); 를 통해서 data에 어떤 값들이 들어오는지 파악할 수 있다 이것을 통해 data.data에 access_token이 존재함을 찾을 수 있다 (code, id, secret을 보내고 access code를 받아온거임)
const accessToken = data.data.access_token;
return res.status(200).send({accessToken : accessToken}) //app client에게 accessToken을 전송해준다
})
.catch((err) => {
return res.status(400)
})
}
const images = require('../resources/resources');
module.exports = (req, res) => {
//이 모듈은 callback모듈을 통해 들어온 access token이 정상적인 경우와 정상적이지 않은 경우의 분기를 나눠서 코드를 작성해야한다
//1. accessToken이 정상적으로 존재하다면 resource server의 images를 client에게 전달한다
//2. accessToken이 정상적으로 존재하지 않는다면 에러 메세지를 보내준다
// console.log(req.headers.authorization); 를 통해서 req.headers에 authorization안에 access token인 'fake_auth_code'가 있음을 알 수 있다
/*
근데 찾을 때 주의해야할 사항은 객체가
[Symbol(kHeaders)]: {
host: '127.0.0.1:53246',
'accept-encoding': 'gzip, deflate',
authorization: 'token fake_access_token',
connection: 'close'
}
이런 식으로 표현되어 있다 그래서 우리는 저 안에 앞의 k값을 제외한 req.headers로 들어가면 authorization에 접근할 수 있다
*/
if(req.headers.authorization) {
return res.status(200).send({images : images}).end()
} else {
return res.status(403).json({message : "no permission to access resources"}).end()
}
}
또 새벽 2시다 자자💤