如何使用 php 在服务器端验证 android 应用收到的 facebook id_token 并获取用户配置文件
How to verify facebook id_token received by android app on server side with php and get user profile
要在我的 android 应用程序上使用 facebook 登录,我请求 public_profile 和用户的电子邮件:
LoginManager.getInstance().logInWithReadPermissions(LoginFragment.this,
Arrays.asList("public_profile", "email"));
然后我将 id_token Profile.getCurrentProfile().getId()
发送到后端服务器。
在服务器端,我尝试按如下方式验证令牌:
$id_token = $_POST['idToken'];
$app_access_token = FB_APP_ID . "|" . FB_APP_SECRET;
$fb = new \Facebook\Facebook(['app_id' => FB_APP_ID,
'app_secret' => FB_APP_SECRET,
'default_graph_version' => 'v2.8',
'default_access_token' => $app_access_token]);
$response = $fb->get('/debug_token?input_token=' . $id_token, $app_access_token);
但是 $response
只包含一个空 json {}
.
更新 1:
与
$oauth = $fb->getOAuth2Client();
$meta = $oauth->debugToken($app_access_token);
我最终设法验证了 id_token。 $meta
包含然后:
["metadata":protected]=>
array(4) {
["app_id"]=>string(16) "123456"
["application"]=>string(10) "abcdef"
["is_valid"]=>bool(true)
["scopes"]=>array(0) {}
}
它还显示虽然我使用 public_profile
和 email
权限调用 logInWithReadPermissions
,但范围数组是空的。我什至在 FacebookCallback
的 onSuccess()
方法中再次检查了权限。但在我将数据存储到数据库之前,我想在服务器端阅读 user_id、user_name 和电子邮件,以确保它们与 id_token.
匹配
更新 2:
当我用 $id_token
而不是 $app_access_token
调用 $oauth->debugToken()
时,我现在得到了我期望的结果。它还显示了我之前设置的权限。但我仍然有一个问题,我不知道如何访问授予的信息(user_name、user_profile_picture、电子邮件等)。
最后我设法解决了整个问题。我想我的主要问题是我不知道何时使用用户访问令牌以及何时使用应用程序访问令牌。在许多讨论甚至文档中,人们只是在谈论访问令牌,而没有具体说明他指的是用户还是应用程序访问令牌。也就是说,这是我的最终解决方案:
$id_token = $_POST['idToken'];
$app_access_token = FB_APP_ID . "|" . FB_APP_SECRET;
$fb = new \Facebook\Facebook(['app_id' => FB_APP_ID,
'app_secret' => FB_APP_SECRET,
'default_graph_version' => 'v2.8',
'default_access_token' => $app_access_token]);
$oauth = $fb->getOAuth2Client();
$meta = $oauth->debugToken($app_access_token);
try {
$meta->validateAppId(FB_APP_ID);
$idTokenIsValid = true;
} catch(FacebookSDKException $e) {
$idTokenIsValid = false;
exit;
}
if($idTokenIsValid){
$resp = $fb->get('/me?fields=id,name,email,first_name,last_name,locale,gender', $id_token);
$user = $resp->getGraphUser();
if($user->getId() != null){
$facebook_id = $user->getId();
$picture = "graph.facebook.com/" . $facebook_id . "/picture";
}
if($user->getName() != null){
$name = $user->getName();
}
$emailIsVerified = false;
if($user->getEmail() != null){
$email = $user->getEmail();
$emailIsVerified = true;
}
if($user->getFirstName() != null){
$given_name = $user->getFirstName();
}
if($user->getLastName() != null){
$family_name = $user->getLastName();
}
if($user->getProperty('locale') != null){
$locale = $user->getProperty('locale');
}
if($user->getProperty('gender') != null){
$gender = $user->getProperty('gender');
}
if($emailIsVerified){
//update db or/and request data from db
}
}
要在我的 android 应用程序上使用 facebook 登录,我请求 public_profile 和用户的电子邮件:
LoginManager.getInstance().logInWithReadPermissions(LoginFragment.this,
Arrays.asList("public_profile", "email"));
然后我将 id_token Profile.getCurrentProfile().getId()
发送到后端服务器。
在服务器端,我尝试按如下方式验证令牌:
$id_token = $_POST['idToken'];
$app_access_token = FB_APP_ID . "|" . FB_APP_SECRET;
$fb = new \Facebook\Facebook(['app_id' => FB_APP_ID,
'app_secret' => FB_APP_SECRET,
'default_graph_version' => 'v2.8',
'default_access_token' => $app_access_token]);
$response = $fb->get('/debug_token?input_token=' . $id_token, $app_access_token);
但是 $response
只包含一个空 json {}
.
更新 1:
与
$oauth = $fb->getOAuth2Client();
$meta = $oauth->debugToken($app_access_token);
我最终设法验证了 id_token。 $meta
包含然后:
["metadata":protected]=>
array(4) {
["app_id"]=>string(16) "123456"
["application"]=>string(10) "abcdef"
["is_valid"]=>bool(true)
["scopes"]=>array(0) {}
}
它还显示虽然我使用 public_profile
和 email
权限调用 logInWithReadPermissions
,但范围数组是空的。我什至在 FacebookCallback
的 onSuccess()
方法中再次检查了权限。但在我将数据存储到数据库之前,我想在服务器端阅读 user_id、user_name 和电子邮件,以确保它们与 id_token.
更新 2:
当我用 $id_token
而不是 $app_access_token
调用 $oauth->debugToken()
时,我现在得到了我期望的结果。它还显示了我之前设置的权限。但我仍然有一个问题,我不知道如何访问授予的信息(user_name、user_profile_picture、电子邮件等)。
最后我设法解决了整个问题。我想我的主要问题是我不知道何时使用用户访问令牌以及何时使用应用程序访问令牌。在许多讨论甚至文档中,人们只是在谈论访问令牌,而没有具体说明他指的是用户还是应用程序访问令牌。也就是说,这是我的最终解决方案:
$id_token = $_POST['idToken'];
$app_access_token = FB_APP_ID . "|" . FB_APP_SECRET;
$fb = new \Facebook\Facebook(['app_id' => FB_APP_ID,
'app_secret' => FB_APP_SECRET,
'default_graph_version' => 'v2.8',
'default_access_token' => $app_access_token]);
$oauth = $fb->getOAuth2Client();
$meta = $oauth->debugToken($app_access_token);
try {
$meta->validateAppId(FB_APP_ID);
$idTokenIsValid = true;
} catch(FacebookSDKException $e) {
$idTokenIsValid = false;
exit;
}
if($idTokenIsValid){
$resp = $fb->get('/me?fields=id,name,email,first_name,last_name,locale,gender', $id_token);
$user = $resp->getGraphUser();
if($user->getId() != null){
$facebook_id = $user->getId();
$picture = "graph.facebook.com/" . $facebook_id . "/picture";
}
if($user->getName() != null){
$name = $user->getName();
}
$emailIsVerified = false;
if($user->getEmail() != null){
$email = $user->getEmail();
$emailIsVerified = true;
}
if($user->getFirstName() != null){
$given_name = $user->getFirstName();
}
if($user->getLastName() != null){
$family_name = $user->getLastName();
}
if($user->getProperty('locale') != null){
$locale = $user->getProperty('locale');
}
if($user->getProperty('gender') != null){
$gender = $user->getProperty('gender');
}
if($emailIsVerified){
//update db or/and request data from db
}
}