PHP SDK:在用户验证应用程序后如何捕获访问令牌? [英] PHP SDK: How do I capture the access token after user auths app?

查看:100
本文介绍了PHP SDK:在用户验证应用程序后如何捕获访问令牌?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是用于Facebook平台上使用最新(最新)Facebook PHP SDK的画布应用程序。



我们正在使用Facebook教程(https中的PHP示例://developers.facebook.com/docs/appsonfacebook/tutorial/)来触发OAuth对话框,并使测试用户使用重定向URL。



在重定向URL ,我们使用Facebook签名请求文档页面(https://developers.facebook.com/docs/authentication/signed_request/)中的PHP示例,我们的测试用户可以成功授权该应用。



但是,在测试用户对应用程序进行身份验证之后,我们将无法捕获访问令牌及其到期。我们可以在附加到重定向URL的地址栏中看到它,但是它不会显示在$ _REQUEST数组中。如果将{$ access_token = $ facebook-> getAccessToken();}添加到重定向URL页面,它将显示访问令牌的值,但显示的值不是当我们单击Show时看到的完整令牌字符串。 测试用户角色页面中的令牌(我们认为这是测试用户的正确访问令牌)。



以下是带有附加访问令牌的重定向URL的示例:
http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php#access_token=126736467765%7C2.AQDavId8oL80P5t9.3600.1315522800.1-100002908746828%7CJICJwM1P_97tKmqkYire&pXDC=7 / a>



这是var_dump在同一页面的$ REQUEST数组中显示的内容:
array(3){[
_qca] =>字符串(26) P0-709927483-1291994912966 [ __switchTo5x] =>字符串(2) 30 [ PHPSESSID] =>字符串(26) euois02ead39ijumca7nffblh2}



我们不知道为什么$ _REQUEST数组不同于附加到URL的值,以及更多重要的是-如何捕获访问令牌及其有效期。



有人可以向我们展示一个运行parse_signed_request($ signed_request, $ secret)重定向页面上的功能?谢谢!



附加信息:



这是A)测试索引页和B中的相关代码)我们的测试重定向页面。如果我们将文本索引页面用作重定向URL,则会陷入无限循环-因为永远不会识别用户。



A)索引页面

  //创建kk-fb应用程序实例
$ facebook = new Facebook(array(
'appId'=> KKFB_ID,
'secret'=> KKFB_KY,
'oauth'=> true,
));

$ app_id = KKFB_ID;
$ secret = KKFB_KY;
$ canvas_auth =‘http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php’;

$ auth_url = https://www.facebook.com/dialog/oauth?
。 client_id =。 $ app_id
。 & redirect_uri =。 urlencode($ canvas_auth)
。 & response_type = token
。 & scope = email,publish_stream;

$ signed_request = $ _REQUEST [ signed_request];

list($ encoded_sig,$ payload)=爆炸(’。’,$ signed_request,2);

$ data = json_decode(base64_decode(strtr($ payload,'-_','+ /')),true);

if(empty($ data [ user_id]])){
echo(< script> top.location.href ='。$ auth_url。'< /脚本>);
} else {
echo( Welcome User:。$ data [ user_id]);
}

B)重定向页面

  //创建kk-fb应用程序实例
$ facebook = new Facebook(array(
'appId'=> KKFB_ID,
'secret '=> KKFB_KY,
'oauth'=> true,
));

$ app_id = KKFB_ID;
$ secret = KKFB_KY;

$ signed_request = $ _REQUEST [ signed_request];

list($ encoded_sig,$ payload)=爆炸(’。’,$ signed_request,2);

$ data = json_decode(base64_decode(strtr($ payload,'-_','+ /')),true);

$ user = $ facebook-> getUser();
$ access_token = $ facebook-> getAccessToken();

echo User:$ user< br>;
echo访问令牌:$ access_token< br>;
echo Signed Request:$ signed_request< br>;
var_dump($ _ REQUEST);

以下是这些回显结果显示的内容:



用户:0
访问令牌:126736467765 | ** SECRET **
签名请求:
array(3) {[ _ qca] =>字符串(26) P0-709927483-1291994912966 [ _switchTo5x] =>字符串(2) 30 [ PHPSESSID] =>字符串( 26) frugi545cdl15gjind1fnv6pq1}



有趣的是,当测试用户返回索引页面时,如果条件满足,我们可以获得正确的访问令牌:



欢迎用户:100002908746828
访问令牌:126736467765 | 2.AQBgcyzfu75IMCjw.3600.1315544400.1-100002908746828 | m5IYEm976tJAkbTLdxHAhhgKmz8



< >显然,我们仍然缺少某些东西!另外,我们还需要学习如何将到期时间作为变量获取,以便将它们都存储在数据库中。

解决方案

好,让我们再试一次。



服务器端与客户端身份验证



使用PHP SDK,因此您要进行服务器端身份验证,其中身份验证代码通过URL通过HTTP发送到服务器。这将允许您在auth(在您的情况下为重定向页面)加载后的第一页加载中为用户获取访问令牌。您当前正在构造的auth_url设置 response_type = token ,这将强制重定向使用客户端身份验证模式,并在URL片段而不是查询中设置令牌。您应该完全删除该参数。实际上,我强烈建议您只使用PHP SDK,而不要自己构造URL。参见下面的示例。



应用程序访问令牌



外观奇怪的访问令牌126736467765 | SECRET 是您的应用程序访问令牌,由您的应用程序ID和密钥组成。如果没有用户访问令牌可用,则 getAccessToken()返回应用程序访问令牌(因为某些API调用至少需要某种访问令牌)。这也意味着您已通过此博客文章向世界透露了您的秘密密钥,因此您应该>重置您的应用程序秘密否则任何人都可以代表您进行API调用。我强烈建议您与他人共享访问令牌的一部分。



令牌到期



OAuth 2.0流程和PHP SDK的v3.1.1使得确定令牌的失效时间变得异常容易。我建议尝试进行API调用,然后在API调用失败并显示<$时,刷新令牌 c $ c> OAuthException 。令牌即使尚未过期也可能无效,因此可以处理更多情况。但是,如果您仍然希望保留到期日期,则可能只想从令牌本身中提取它。如果您有一个到期令牌,那么到期时间戳将包含在该字符串中。这是我快速汇总的一个函数,用于提取该函数:

 函数extractExpirationFromToken($ access_token){
$ segments = explode ('|',$ access_token);
if(count($ segments)< 2){返回0; }

$ segments = explode(’。’,$ segments [1]);
if(count($ segments)< 4){返回0; }

$ expires = $ segments [3];
$ dash_pos = strrpos($ expires,’-’);
if($ dash_pos!== false){
$ expires = substr($ expires,0,$ dash_pos);
}
返回$ expires;
}



新索引页代码



  //创建kk-fb应用程序实例
$ facebook = new Facebook(array(
'appId'=> KKFB_ID,
'secret '=> KKFB_KY,
));

$ canvas_auth =‘http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php’;

$ auth_url = $ facebook-> getLoginUrl(array(
'scope'=>'email,publish_stream',
'redirect_uri'=> $ canvas_auth,/ /您可以通过
)重定向回该索引页面;

$ user = $ facebook-> getUser();

if(empty($ user)){
echo(< script> top.location.href ='。$ auth_url。’< / script>));
} else {
echo( Welcome User:。$ user);
}



重定向页面



我认为您根本不需要此页面。您只需将用户重定向到原始索引页面即可。

  //创建kk-fb应用实例
$ facebook = new Facebook(array(
'appId'=> KKFB_ID,
'secret'=> KKFB_KY,
));

$ user = $ facebook-> getUser();
$ access_token = $ facebook-> getAccessToken();
//也复制先前给出的函数定义
$ expiration = extractExpirationFromToken($ access_token);

echo User:$ user< br>;
echo访问令牌:$ access_token< br>;
echo Expiration:$ expiration< br>;
echo Request:< br>;
var_dump($ _ REQUEST);


This is for a canvas app on the Facebook Platform using the new(est) Facebook PHP SDK.

We are using the PHP example from the Facebook tutorial (https://developers.facebook.com/docs/appsonfacebook/tutorial/) to trigger the OAuth dialog and get the test user to the redirect URL.

At the redirect URL, we use the PHP example from the Facebook signed request docs page (https://developers.facebook.com/docs/authentication/signed_request/) and our test users can successfully authorize the app.

However, after the test user auths the app, we are not able to capture the access token and its expiration. We can see it in the address bar appended to the redirect URL, but it does not show up in the $_REQUEST array. If we add {$access_token = $facebook->getAccessToken();} to the redirect URL page, it shows a value for the access token, but the value it shows is not the full token string that we see when we click on Show Token in the Test User Roles page (which we believe is the correct access token for the test user).

Here is an example of the redirect URL with an access token appended: http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php#access_token=126736467765%7C2.AQDavId8oL80P5t9.3600.1315522800.1-100002908746828%7CJICJwM1P_97tKmqkEO5pXDCf-7Y&expires_in=6008

Here is what var_dump shows for the $REQUEST array for that same page: array(3) { ["_qca"]=> string(26) "P0-709927483-1291994912966" ["__switchTo5x"]=> string(2) "30" ["PHPSESSID"]=> string(26) "euois02ead39ijumca7nffblh2" }

We have no idea why the $_REQUEST array varies from the values appended to the URL, and more importantly -- how to capture the access token and its expiration date.

Can someone show us a working example of how they capture this data after running the parse_signed_request($signed_request, $secret) function on the redirect page? Thanks!

ADDITIONAL INFO:

Here is the pertinent code from A) our test index page, and B) our test redirect page. If we use our text index page as the redirect url it gets stuck in an endless loop -- because the user is never identified.

A) Index Page

// Create kk-fb app instance
$facebook = new Facebook(array(
    'appId'  => KKFB_ID,
    'secret' => KKFB_KY,
    'oauth' => true,
));

$app_id = KKFB_ID;
$secret = KKFB_KY;
$canvas_auth = 'http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php';

$auth_url = "https://www.facebook.com/dialog/oauth?" 
                . "client_id=" . $app_id 
                . "&redirect_uri=" . urlencode($canvas_auth) 
                . "&response_type=token" 
                . "&scope=email,publish_stream";

$signed_request = $_REQUEST["signed_request"];

list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);

if (empty($data["user_id"])) {
    echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
    echo ("Welcome User: " . $data["user_id"]);
}

B) Redirect Page

// Create kk-fb app instance
$facebook = new Facebook(array(
    'appId'  => KKFB_ID,
    'secret' => KKFB_KY,
    'oauth' => true,
));

$app_id = KKFB_ID;
$secret = KKFB_KY;

$signed_request = $_REQUEST["signed_request"];

list($encoded_sig, $payload) = explode('.', $signed_request, 2); 

$data = json_decode(base64_decode(strtr($payload, '-_', '+/')), true);

$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();

echo "User: $user <br>";
echo "Access Token: $access_token <br>";
echo "Signed Request: $signed_request <br>";
var_dump($_REQUEST);

Here is what shows up as these echo results:

User: 0 Access Token: 126736467765|**SECRET** Signed Request: array(3) { ["_qca"]=> string(26) "P0-709927483-1291994912966" ["_switchTo5x"]=> string(2) "30" ["PHPSESSID"]=> string(26) "frugi545cdl15gjind1fnv6pq1" }

Interestingly, when the test user goes back to the index page the if condition is satisfied and we can get the correct access token:

Welcome User: 100002908746828 Access Token: 126736467765|2.AQBgcyzfu75IMCjw.3600.1315544400.1-100002908746828|m5IYEm976tJAkbTLdxHAhhgKmz8

Obviously, we are still missing something!? Also, we need to learn how to get the expiration time as a variable too so we can store both of these in our database.

解决方案

OK, let's try this again.

Server-side vs Client-side Authentication

You are exclusively using the PHP SDK, so you want to do server-side authentication, where the authentication code is sent to the server over HTTP via the URL. This will allow you to fetch an access token for the user on the first page load after auth (in your case, the redirect page). The auth_url you are currently constructing is setting response_type=token, which forces the redirect to use client-side auth mode and set the token in the URL fragment instead of in the query. You should remove that parameter completely. In fact, I highly recommend you just use the PHP SDK instead of constructing that URL yourself. See example below.

Application Access Tokens

The odd-looking access token 126736467765|SECRET is your application access token, which is composed of your app ID and secret key. The application access token is returned by getAccessToken() if no user access token is available (because some API calls require at least some sort of access token). This also means that you've revealed your secret key to the world via this blog post, so you should reset your app secret otherwise anyone will be able to make API calls on your behalf. I highly recommend you elide parts of your access tokens if you share them with others.

Token Expiration

The OAuth 2.0 flow and v3.1.1 of the PHP SDK don't make determining the expiration time of a token all that easy. I would suggest attempting to make the API call, and then refreshing the token if the API call fails with an OAuthException. Tokens can be invalid even if they haven't expired, so this deals with more cases. However, if you still want to maintain the expiration date on your end, you might just want to extract it from the token itself. If you have an expiring token, then the expiration timestamp will be contained within that string. Here's a function I put together quickly to extract that:

function extractExpirationFromToken($access_token) {
    $segments = explode('|', $access_token);
    if(count($segments) < 2) { return 0; }

    $segments = explode('.', $segments[1]);
    if(count($segments) < 4) { return 0; }

    $expires = $segments[3];
    $dash_pos = strrpos($expires, '-');
    if($dash_pos !== false) {
        $expires = substr($expires, 0, $dash_pos);
    }
    return $expires;
}

New Index Page Code

// Create kk-fb app instance
$facebook = new Facebook(array(
    'appId'  => KKFB_ID,
    'secret' => KKFB_KY,
));

$canvas_auth = 'http://karmakorn.com/karmakorn/alpha20/kk-fb-auth.php';

$auth_url = $facebook->getLoginUrl(array(
    'scope' => 'email,publish_stream',
    'redirect_uri' => $canvas_auth, // you could just redirect back to this index page though
));

$user = $facebook->getUser();

if (empty($user)) {
    echo("<script> top.location.href='" . $auth_url . "'</script>");
} else {
    echo ("Welcome User: " . $user);
}

Redirect Page

I don't think you need this page at all. You could just redirect the user back to your original index page.

// Create kk-fb app instance
$facebook = new Facebook(array(
    'appId'  => KKFB_ID,
    'secret' => KKFB_KY,
));

$user = $facebook->getUser();
$access_token = $facebook->getAccessToken();
// also copy the function definition given earlier
$expiration = extractExpirationFromToken($access_token);

echo "User: $user <br>";
echo "Access Token: $access_token <br>";
echo "Expiration: $expiration <br>";
echo "Request: <br>";
var_dump($_REQUEST);

这篇关于PHP SDK:在用户验证应用程序后如何捕获访问令牌?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆