如何使用 OAuth 刷新令牌更新访问令牌?
How to renew access token with OAuth Refresh token?
我正在为 Uber 创建简单的应用程序。
我已经解决了 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() 或其他方法来解决此任务?
首先,根据STEP FIVE: REFRESHING TOKENS from the Authentication docs,刷新访问令牌需要HTTPPOST以下参数:
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 端点
您还发送了 code 参数,这意味着您将收到错误消息,因为此附加参数无法在 Uber 的服务器上验证。
您得到的错误将是
HTTP/1.1 401 UNAUTHORIZED
{"error": "invalid_grant"}
为了能够检查令牌有效性,在将代码与访问令牌交换之后,您需要:
在某处保留 "access_token"、"expires_in"、"refresh_token" 和一个以秒为单位的 UNIX 时间戳,代表当前时间和日期,我们称它为 "itime".
您可以存储此信息的位置多种多样:会话、文件、数据库、内存缓存等,具体取决于您希望如何处理令牌过期和自动用户登录(如果您已经保存了他们的令牌并且没有过期,那么您就不必让用户再次登录。
在您向优步发出每个 HTTP 请求之前 API 您首先通过检索 "itime" 和 "expires_in" 检查访问令牌是否已过期从用户访问令牌的存储位置并确保 time() < "itime"+"expires_in" 成立。
如果条件为假,则需要刷新访问令牌。
请记住,刷新访问令牌也会更改刷新令牌,因此您需要将当前的 "access_token"、"refresh_token" 和 "expires_in" 替换为由 uuid 标识的当前用户。
- 鉴于访问令牌的当前过期时间是 30 天(2592000 秒),我建议您将访问令牌数据存储在数据库中 table,因为 PHP 会话是短暂的(默认情况下 session.gc_maxlifetime 在 php.ini 中是 1440 seconds/24 分钟)并且用户也不会一直停留在你的 app/website 上。
- 此外,如果您允许用户从多个 devices/places 登录 Uber,检查过期时间是不够的,因为在每个用户登录后,所有先前的 access/refresh 令牌都将失效。因此,当用户在第二台设备上登录后,您可能会在第一台设备上看到具有有效到期时间的无效 access/token。
在这种情况下,为了确定访问令牌是否仍然有效,我建议您使用访问令牌向 GET /v1/me 端点发出额外的 HTTP 请求。如果有效,则令牌仍然有效,否则 expired/was 无效,您需要请求用户在第一台设备上重新登录。
tl;dr 你不需要计时器,你需要在每个 HTTP 请求到 Uber API 之前检查访问令牌是否仍然有效。
为此,您需要保留令牌详细信息 + UNIX 时间戳。
我正在为 Uber 创建简单的应用程序。
我已经解决了 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() 或其他方法来解决此任务?
首先,根据STEP FIVE: REFRESHING TOKENS from the Authentication docs,刷新访问令牌需要HTTPPOST以下参数:
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 端点
您还发送了 code 参数,这意味着您将收到错误消息,因为此附加参数无法在 Uber 的服务器上验证。 您得到的错误将是
HTTP/1.1 401 UNAUTHORIZED {"error": "invalid_grant"}
为了能够检查令牌有效性,在将代码与访问令牌交换之后,您需要:
在某处保留 "access_token"、"expires_in"、"refresh_token" 和一个以秒为单位的 UNIX 时间戳,代表当前时间和日期,我们称它为 "itime".
您可以存储此信息的位置多种多样:会话、文件、数据库、内存缓存等,具体取决于您希望如何处理令牌过期和自动用户登录(如果您已经保存了他们的令牌并且没有过期,那么您就不必让用户再次登录。
在您向优步发出每个 HTTP 请求之前 API 您首先通过检索 "itime" 和 "expires_in" 检查访问令牌是否已过期从用户访问令牌的存储位置并确保 time() < "itime"+"expires_in" 成立。
如果条件为假,则需要刷新访问令牌。请记住,刷新访问令牌也会更改刷新令牌,因此您需要将当前的 "access_token"、"refresh_token" 和 "expires_in" 替换为由 uuid 标识的当前用户。
- 鉴于访问令牌的当前过期时间是 30 天(2592000 秒),我建议您将访问令牌数据存储在数据库中 table,因为 PHP 会话是短暂的(默认情况下 session.gc_maxlifetime 在 php.ini 中是 1440 seconds/24 分钟)并且用户也不会一直停留在你的 app/website 上。
- 此外,如果您允许用户从多个 devices/places 登录 Uber,检查过期时间是不够的,因为在每个用户登录后,所有先前的 access/refresh 令牌都将失效。因此,当用户在第二台设备上登录后,您可能会在第一台设备上看到具有有效到期时间的无效 access/token。 在这种情况下,为了确定访问令牌是否仍然有效,我建议您使用访问令牌向 GET /v1/me 端点发出额外的 HTTP 请求。如果有效,则令牌仍然有效,否则 expired/was 无效,您需要请求用户在第一台设备上重新登录。
tl;dr 你不需要计时器,你需要在每个 HTTP 请求到 Uber API 之前检查访问令牌是否仍然有效。
为此,您需要保留令牌详细信息 + UNIX 时间戳。