PHP/PHP

[PHP]페이스북 로그인 연동하기(curl 사용)

테서르 2022. 2. 23. 15:07
반응형

📢 이 게시글은 아래의 사양에서 테스트하였습니다.

Server OS : Ubuntu 20.04.3 LTS
WebServer : Apache 2.4
Backend : PHP 8.1

 

앱 생성 및 기본 설정 방법과 공식 PHP SDK를 사용하는 방법은 https://teserre.tistory.com/2를 참조해 주세요.

 

처음 페이스북 API를 사용할 때는 공식 SDK를 사용하여 작업을 했다. 그러다 PHP 8버전이 괜찮다고 하여 버전을 변경하였더니 업그레이드 되면서 PHP 기능의 일부가 삭제가 되어 오류가 출력되었다.

공식 github는 2018년을 마지막으로 커밋이 이루어지지 않았고 PHP 8을 지원할 생각이 없어보였다. 개발자 문서에서도 PHP SDK 링크가 올바르게 작동하지 않는 것을 보면 사실상 지원이 중단되었다고 생각된다.

 

그래서 검색을 해 보니 다행히 URL로 직접 요청하여 로그인을 하는 방식에 대해 문서가 작성되어 있었다. 이를 토대로 PHP 코드를 작성해 보았다.

링크: https://developers.facebook.com/docs/facebook-login/manually-build-a-login-flow?locale=ko_KR 

 

로그인 플로 직접 빌드 - Facebook 로그인 - 문서 - Facebook for Developers

사용자 로그인 유도 사용자가 앱에 로그인하지 않았거나 Facebook에 로그인하지 않은 경우 로그인 대화 상자를 사용하여 앱과 Facebook에 모두 로그인하도록 메시지를 표시할 수 있습니다. Facebook에

developers.facebook.com

 

로그인을 하기 위해서는 로그인을 요청할 주소를 생성해야 한다. 로그인 요청 주소를 보면 페이스북 앱의 아이디, 결과를 받을 리디렉션 주소, 사용자에게 요청할 주소, 그리고 탈취 방지를 위한 임의 문자열로 구성되어있다.

https://www.facebook.com/v13.0/dialog/oauth?
  client_id={app-id}	//페이스북 앱 아이디
  &redirect_uri=https://www.domain.com/login	//로그인 요청을 처리할 주소
  &state={"{st=state123abc,ds=123456789}"}	// 임의 문자열
  &scope=public_profile,email	//요청할 권한 목록

이를 토대로 PHP 코드를 작성하면 아래처럼 할 수 있다.

$state = bin2hex(openssl_random_pseudo_bytes(16));	//탈취 방지위한 랜덤문자열
$appID = 'facebook app-id';	//페이스북 앱 아이디
$redirectUri = urlencode("https://example.com/callback.php");	//로그인 요청 처리할 주소
$permissions = urlencode('public_profile,email');	//요청할 권한

//로그인 주소 생성
$loginUrl = "https://www.facebook.com/v13.0/dialog/oauth?client_id=$appID&state=$state&redirect_uri=$redirectUri&scope=$permissions";

state는 PHP SDK로 로그인 처리시 생성되는 주소를 확인해 보니 16진수로 32자리 문자열을 생성하고 있었다. 그래서 openssl로 2진 데이터 16바이트를 생성 후 16진수로 변환하여 나온 32자리 랜덤 문자열을 사용한다.

권한은 별다른 검수 없이 바로 사용할 수 있는 계정 프로필과 이메일을 사용하였다. 원하는 권한이 있다면 저기에 추가를 하면 된다.

리디렉션 URI와 요청 권한에 urlencode를 한 이유는 URI에 특수문자가 있다면 오류가 발생하니 안전을 위해 인코딩을 한 것이다. 공식 SDK 또한 인코딩 처리를 하여 생성한다.

 

이렇게 생성된 로그인 주소를 클릭하면 페이스북 로그인 화면이 출력된다. 브러우저로 페이스북 로그인을 한 상태라면 자동으로 해당 페이스북 앱의 연동 화면이 출력된다. 이미 페이스북에 로그인이 되어있고 public_profile 권한이나 email 권한만 사용하는 경우 별도의 로그인 창이 뜨지 않는다.

 

페이스북에서 로그인을 하고 요청을 처리할 리디렉션 주소로 이동이 되었다면 주소의 파라미터에 code가 추가된 것을 볼 수 있다. 이것을 사용하여 액세스 토큰을 요청한다.

# 로그인 후 응답요청 처리할 callback.php
$code = $_GET['code']; //응답받은 code 파라미터
$appID = 'facebook app-id';	//페이스북 앱 아이디
$appSecret = 'facebook app secret';	//페이스북 앱 시크릿
$redirectUri = urlencode("https://example.com/callback.php");	//로그인 요청 처리할 주소와 같은 주소

// 액세스 토큰을 받을 주소
$tokenUrl = "https://graph.facebook.com/v13.0/oauth/access_token?client_id=$appID&redirect_uri=$redirectUri&client_secret=$appSecret&code=$code";

// curl로 get 요청
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $tokenUrl);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response = json_decode(curl_exec($curl));

//액세스 토큰 변수에 저장
$accessToken = $response->access_token;

// 장기 토큰으로 변환
$url = "https://graph.facebook.com/v13.0/oauth/access_token?grant_type=fb_exchange_token&client_id=$appID&client_secret=$appSecret&fb_exchange_token=$accessToken";
curl_setopt($curl, CURLOPT_URL, $url);
$response = json_decode(curl_exec($curl));

// 저장된 토큰 변경
$accessToken = $response->access_token;

이렇게 하면 로그인한 계정의 데이터에 접근할 수 있는 액세스 토큰이 발급이 된다. var_dump로 결과를 출력 해 보면 access_token 항목이 있다. 이 액세스 토큰을 사용해야 사용자가 허락한 권한에 대하여 계정 데이터를 획득할 수 있다.

여기서 발급된 토큰은 마찬가지로 단기 토큰으로 1~2시간 정도의 수명을 가지고 있다. 필요에 따라 약 60일 정도의 수명을 가진 장기 토큰으로 변환을 할 수 있다.

 

// 계정정보 확인
$url = "https://graph.facebook.com/v13.0/me?fields=id,name,picture,email&access_token=$accessToken";
curl_setopt($curl, CURLOPT_URL, $url);
$profile = json_decode(curl_exec($curl));

// 데이터 변수에 각자 저장
$email = $profile->email;
$pictureUrl = $profile->picture->data->url;
$name = $profile->name;

데이터를 요청할 그래프 api 주소를 입력하고 발급받은 액세스 토큰을 추가하여 get 요청을 하면 데이터를 얻을 수 있다.

아래의 변수에 개별 저장하는 것은 응답 데이터의 구조를 확인하기 위함이라 굳이 개별 저장을 할 필요는 없다.

 

작성하고 보니 생각보다 간단해서 굳이 SDK를 사용하지 않아도 될 것 같다. 어차피 그래프 api를 사용하려면 curl로 하는 게 편하다.

참고로 페이스북 API를 통해 얻은 이미지의 주소는 대략 3~4일 정도만 조회가 가능하다. 그래서 필요한 경우 별도로 저장을 하거나 로그인을 할 때마다 주소를 얻어 교체해 주어야 한다.

 

반응형

'PHP > PHP' 카테고리의 다른 글

[PHP] php 세션(Session) 사용하기  (4) 2021.02.22
[PHP]페이스북 로그인 API 연동하기(공식 SDK 사용)  (19) 2021.01.29