如何使用OAuth刷新令牌续订访问令牌?

时间:2016-04-20 12:53:15

标签: php oauth uber-api

我正在为优步创建简单的应用程序 我已经从这个API中解决了3个步骤:https://developer.uber.com/docs/authentication
但现在我想刷新令牌(步骤5) 我收到access_token,refresh_token,expires_in值,当expires_in时间到期时,我无法理解如何设置计时器以刷新用户的令牌和refresh_token。
这里我提供了我的代码示例,我想用refresh_token更新访问令牌。

<?php
session_start();

require_once 'uber_b.php';
require_once 'config.php';


if(isset($_GET['code'])) {
// try to get an access token
$code = $_GET['code'];
$url = 'https://login.uber.com/oauth/token';

/* 
* Create row for function setPostData (uber_b.php)
* All of this rows will be used to build our request
*/
$params = array(
    "code" => $code,
    "client_id" => $client_id,
    "client_secret" => $client_secret,
    "redirect_uri" => $redirect,
    "grant_type" => "authorization_code"
);
//create example of class
$request = new HttpPost($url);
//Connect this class with our settings
$request->setPostData($params);
//Send our request to Uber
$request->send(); 
//Receive response
$responseObj = json_decode($request->getHttpResponse());
//Execute parameters from answer
$user_token = $responseObj->access_token;
//Refresh token 
$refresh_token = $responseObj->refresh_token;
//Time for token
$expires_in = $responseObj->expires_in;

echo "User's token: " . $user_token;
echo "<br>";
echo "Refresh token is: " .$refresh_token ;
echo "<br>";
echo "Time: ".$expires_in;
echo "<br>";
echo "<a href='order.php'>Order a car</a>";
}

//Refresh token
if(isset($responseObj))
{
        $exp_time = time()+2592000;
        try {
            //insert into database
            $stmt = $db->prepare('INSERT INTO token2 (exp_time)
                                      VALUES (:exp_time)
                                    ');
            $stmt->execute(array(
                ':exp_time' => $exp_time
            ));             
        } catch(PDOException $e) {
            echo $e->getMessage();
        }
}
if(time() >= $exp_time)
{
//Parameters for Uber refresh token request(step 5)
$r_params = array(
    "client_id" => $client_id,
    "client_secret" => $client_secret,
    "redirect_uri" => $redirect,
    "grant_type" => "refresh_token",
    "refresh_token" => $refresh_token
    );
 $r_request = new RefreshToken($url);

 $r_request->setPostData($r_params);
 $r_request->send(); 
 $refresh = $refresh_token;
 $r_responseObj = json_decode($r_request->Refresh());

echo "New Refresh token: " . $r_responseObj->refresh_token;
echo "<br>";
}
?>

如您所见,我不提供计时器功能,因为我不明白如何使它正确 那么,你能解释一下如何使用refresh_token正确更新access_token吗?
也许我必须使用setcookie()或其他东西来解决这个任务?

1 个答案:

答案 0 :(得分:2)

  • 首先,根据STEP FIVE: REFRESHING TOKENS中的Authentication docs,要刷新访问令牌,您需要HTTP POST以下参数:

    client_secret = YOUR_CLIENT_SECRET
    CLIENT_ID = YOUR_CLIENT_ID
    grant_type = refresh_token
    REDIRECT_URI = YOUR_REDIRECT_URI
    refresh_token = REFRESH_TOKEN

    https://login.uber.com/oauth/v2/token API端点

    您还发送代码参数,这意味着您将收到错误,因为此附加参数无法在Uber服务器上验证。 你得到的错误是

    HTTP/1.1 401 UNAUTHORIZED
    {"error": "invalid_grant"}  
    
  • 为了能够检查令牌的有效性,在您使用访问令牌交换代码后,您需要:

    • 将“access_token”,“expires_in”,“refresh_token”和UNIX时间戳(以秒为单位)保留在某处,表示当前时间和日期,我们称之为“itime”。

    • 您可以存储此信息的位置多种多样:会话,文件,数据库,内存缓存等,具体取决于您希望如何处理令牌过期以及自动用户登录(如果您已保存其令牌)并且它没有过期,那么您不必再次登录用户。

    • 在您对Uber API发出的每个HTTP请求之前,首先通过从用户的访问令牌的存储位置检索“itime”和“expires_in”来检查访问令牌是否已过期。确保时间()&lt; “itime”+“expires_in”成立 如果条件为false,则需要刷新访问令牌。

    • 请记住,刷新访问令牌也会更改刷新令牌,因此您需要为uuid标识的当前用户替换当前的“access_token”,“refresh_token”和“expires_in”。

    • 鉴于访问令牌的当前到期时间是30天(2592000秒),我建议您将访问令牌数据存储在数据库表中,因为PHP会话是短暂的(默认情况下session.gc_maxlifetime是1440)在php.ini中的秒/ 24分钟),用户也不会一直呆在你的应用程序/网站上。
    • 此外,如果允许用户从多个设备/位置登录Uber,则检查过期时间是不够的,因为在每次用户登录后,所有先前的访问/刷新令牌都将失效。因此,在用户登录第二台设备后,您可能在第一台设备上拥有无效的访问/令牌,并且有效的到期时间。 在这种情况下,要确定访问令牌是否仍然有效,我建议您使用访问令牌向GET /v1/me端点发出额外的HTTP请求。如果它有效,则令牌仍然有效,否则它已过期/无效,您需要请求用户在第一台设备上重新登录。

tl; dr您不需要计时器,您需要在每次向Uber API发出HTTP请求之前检查访问令牌是否仍然有效。
为此,您需要保留令牌详细信息+ UNIX时间戳。