Facebook에서 OAuth 구현해보기
간단하게 Oauth를 사용해보는 것을 목적으로 한 포스팅입니다.
용어
- Resource Owner: 사용자
- Resource Server: 사용자의 정보를 가지고 있는 서비스(google, facebook 등)
- Client: 내가 개발한 어플리케이션 및 서비스
목표
facebook으로 로그인하기를 이용하여 내 계정에 대한 정보 받아보기
(= facebook에서 사용자의 access token
발급 받기)
진행 과정
- 페이스북 앱 생성 및 설정
- 테스트를 위한 웹 서버 올리기
- ‘facebook 로그인하기’를 제공할 페이지 작성
- 사용자(나)에게 권한 요청 후 승인
- facebook에서 내 정보 요청해서 출력하기
참고
https://github.com/Delf-Lee/OAuth-tutorial
1. 페이스북 앱 생성 및 설정
- facebook에 앱을 생성합니다.
- Client ID, Client Secret을 발급 받습니다.(facebook에서는 앱 ID, 앱 시크릿 코드)
- Redirection URI를 설정합니다.
절차
- Facebook for developer 가입 및 로그인
- [내 앱] - [새 앱 만들기]
- 표시 이름, 이메일 기입
- [앱 만들기]
- [제품 추가] - [Facebook 로그인] - 설정
- [웹] 선택
- 서비스 제공할 URL 입력 - [Save]
- 여기서는 https://localhost:8000/ 을 입력하였습니다.
- [facebook 로그인] - [설정] - 유효한 OAuth 리디렉션 URI
- Redirection URI 입력
- https://localhost:8000/OAuth-tutorial (이 예제에서 사용할 주소입니다)
Redirection URI는 Client에서 facebook 로그인 기능을 제공할 페이지의 URI입니다.
2. 웹 서버 올리기
어떤 웹 서버든 상관 없지만, 이 과정에서는 간단하게 nodejs에서 제공하는 loacl-web-server를 사용하겠습니다.
- npm: local-web-server
- 설치:
npm install -g local-web-server
- 실행:
ws --https - https
3. facebook 로그인하기를 제공할 페이지 작성
- 방법 1. URL을 이용한 직접 요청
- 방법 2. Javascript SDK를 이용한 요쳥
방법 1. URL을 이용한 직접 요청
- 목표
- ‘권한승인 바로가기’를 누르면 facebook 권한설정 페이지으로 이동
- 승인 완료 후, facebook에서 내 정보를 가져와서 이름 출력
- 개발자 도구로 응답 메시지 확인
<html>
<body>
<div id="notice">
이 기능을 이용하기 위해서는 facebook에서 권한을 승인해야 합니다.
<!-- Resouce Owner가 Resouce Server에게 요청할 URL-->
<a href="https://www.facebook.com/v3.2/dialog/oauth?
client_id={app-id}
&redirect_uri={redirect-uri}
&state={state-param}
&scope=email">
권한승인 바로가기</a>
</div>
<div id="welcome" style="display:none"></div>
<!-- 송수신 확인을 위한 스크립트 -->
<script>
var atr = location.href.match('access_token=([^&]*)'); // 문자열 파싱
console.log('access token regular expression : ', atr);
if (atr) {
var access_token = atr[1]; // 토큰 추출
console.log('access token : ', access_token);
fetch(
"https://graph.facebook.com/v3.2"
+ "/me"
+ "/?access_token=" + access_token
+ "&fields=name, email" // 이름과 이메일 요청
)
.then(function (raw) {
return raw.json();
})
.then(function (result) {
if (result.error) {
} else {
console.log(result);
document.querySelector('#notice').style.display = 'none';
document.querySelector('#welcome').style.display = 'block';
document.querySelector('#welcome').innerHTML = "Welcome, " + result.name;
}
})
}
</script>
</body>
</html>
리디렉션 할 URL과 필수 매개변수
-
https://www.facebook.com/v3.2/dialog/oauth?
client_id={app-id}
&redirect_uri={redirect-uri}
&state={state-param} app-id
앱의 대시보드에 있는 앱 ID입니다.- redirect_uri
사용자가 다시 로그인하도록 리디렉션할 URL입니다. facebook 앱에서 등록된 유효한 OAuth 리디렉션 URI이어야 합니다. 지금은 현재 페이지로 설정해줍니다. (ex> https://localhost:8000/OAuth-tutorial) - state:
요청과 콜백 간에 상태를 관리하기 위해 앱에서 생성하는 문자열 값입니다. 이 매개변수는 사이트 간 요청 위조를 차단하는 데 사용되어야 하며, 리디렉션 URI에서 변경되지 않은 상태로 개발자에게 다시 전달됩니다.
매개변수 scope
필수는 아니지만, Client가 Resource Server에서 접근수 있는 Resource owner의 정보의 범위를 표기합니다. 예제에선 1234
라는 임시 값을 넣어주었습니다.
- URL에
...&scope={scope_name}
추가 - scope의 종류 참고: 권한 참조 - Facebook 로그인
결과
- 권한 바로가기를 누릅니다.
- 이미 권한이 있다면, 로그인 화면은 나타나지 않습니다.
- 권한 승인 후 URL이 변경된 것을 확인할 수 있습니다. 이렇게 전달 받은 값(
access token
)으로 사용자의 정보에 접근할 때 이용할 수 있습니다.https://localhost:8000/oauth-test/fb-low.html
#state=1234++++++++
&access_token=EAADlUGrSbD4BALDg1675ypt9ZAbCI8axbVv1d3H0Du963ntL5q7AkRwrrR3GWhOAZB2NsUZAdUq5JPUZAP08Tmu8yjTvnB3bTYOvwwIJjYzO4xU7Sd71a2mSxlqR2TZBxCsfGJJZCzcftK8htv6edsO5mXOKhYcZCDYIwZC8sy2sLRtZAqMZAgZBJoxn1p2ZA7HMZB74ZD&expires_in=7168
&reauthorize_required_in=7776000
&data_access_expiration_time=1549695632
방법 2. Javascript SDK를 이용한 요쳥
- 결과
- 로그인이 안되었다면
로그인
버튼 띄우기 - 로그인이 되었지만, 권한 승인이 안되있으면 facebook 권한설정 페이지로 이동
- 로그인이 되었고, 권한 승인도 되어있으면 이름과
로그아웃
버튼 띄우기
- 로그인이 안되었다면
- 구현
FB.getLoginStatus()
를 통해 로그인 여부를 확인합니다.- response 값에
access token
값이 포함되어 있습니다.
- response 값에
- 로그인 여부에 따라
FB.login()
를 이용하여 로그인을 유도합니다.
<html>
<body>
<div id="welcome"></div>
<div id="notice">
<input type="button" id="authBtn" value="checking..." onclick="
if(this.value === 'Login'){
FB.login(function(response){
refreshAuthStatus();
}, {scope:'email'}); // scope 설정 가능
} else {
FB.logout(function(response){
refreshAuthStatus();
});
}
">
</div>
<script>
function refreshAuthStatus() {
FB.getLoginStatus(function (response) {
console.log('FB.getLoginStatus', response);
if (response.status === 'connected') {
FB.api('/me', function (response) { // me, 혹은 사용자 id 입력
document.querySelector('#authBtn').value = 'Logout';
document.querySelector('#welcome').innerHTML = 'Welcome, ' + response.name;
})
} else {
document.querySelector('#authBtn').value = 'Login';
document.querySelector('#welcome').innerHTML = '';
}
});
}
window.fbAsyncInit = function () {
FB.init({
appId: '{app-id}', // app-id 입력하기
autoLogAppEvents: true,
xfbml: true,
version: 'v3.2'
});
console.log('Init');
refreshAuthStatus();
};
(function (d, s, id) {
var js, fjs = d.getElementsByTagName(s)[0];
if (d.getElementById(id)) {
return;
}
js = d.createElement(s);
js.id = id;
// js.src = "https://connect.facebook.net/ko_KR/sdk.js";
js.src = "https://connect.facebook.net/en_US/sdk.js";
fjs.parentNode.insertBefore(js, fjs);
}(document, 'script', 'facebook-jssdk'));
</script>
</body>
</html>
결과
로그인하기 전
authResponse
의status
값이 not_authorized인 것을 확인할 수 있습니다.
마찬가지로 권한 승인이 되어 있다면 이 화면은 나타나지 않습니다.
방법 1에서 URL로 받았던
access token
값이 이번엔authResponse
에 포함되어 있는 것을 확인할 수 있습니다.
기타
facebook에서 권한 해제를 하고싶다면, [설정] - [앱 및 웹 사이트]에서 해당하는 앱을 삭제합니다.