在使用PHP访问API时,access_token
通常用于身份验证和授权。access_token
的有效期取决于API提供者的设置,可能从几分钟到几小时不等。一旦 access_token
过期,你需要重新获取一个新的 access_token
。
以下是一个基本的流程,展示了如何在PHP中使用 access_token
访问API,并处理 access_token
过期的情况:
-
获取
access_token
:
通常,你需要通过OAuth2.0流程获取access_token
。这通常涉及重定向用户到认证服务器,用户登录并授权后,认证服务器会重定向回你的应用,并附带一个授权码(code)。然后,你可以使用这个授权码去获取access_token
。 -
存储
access_token
和其过期时间:
获取access_token
后,你需要存储它及其过期时间(通常是一个时间戳)。 -
访问API:
在访问API时,检查access_token
是否有效。如果无效,则重新获取一个新的access_token
。 -
处理
access_token
过期:
如果access_token
过期,捕获异常,并重新获取新的access_token
,然后重试请求。
以下是一个示例代码,展示了上述流程:
<?php class ApiClient
{ private $clientId; private $clientSecret; private $redirectUri; private $tokenUrl; private $apiUrl; private $accessToken; private $tokenExpires; public function __construct($clientId, $clientSecret, $redirectUri, $tokenUrl, $apiUrl) { $this->clientId = $clientId; $this->clientSecret = $clientSecret; $this->redirectUri = $redirectUri; $this->tokenUrl = $tokenUrl; $this->apiUrl = $apiUrl; } // 获取新的 access_token private function getNewAccessToken($code) { $url = $this->tokenUrl; $data = [ 'client_id' => $this->clientId, 'client_secret' => $this->clientSecret, 'redirect_uri' => $this->redirectUri, 'code' => $code, 'grant_type' => 'authorization_code' ]; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; $context = stream_context_create($options); $result = file_get_contents($url, false, $context); if ($result === FALSE) { throw new Exception("Error occurred during fetching access token."); } $response = json_decode($result, true); if (!isset($response['access_token']) || !isset($response['expires_in'])) { throw new Exception("Invalid response received."); } $this->accessToken = $response['access_token']; $this->tokenExpires = time() + $response['expires_in']; } // 刷新 access_token(如果需要) private function refreshAccessToken() { $url = $this->tokenUrl; $data = [ 'client_id' => $this->clientId, 'client_secret' => $this->clientSecret, 'grant_type' => 'refresh_token', 'refresh_token' => $this->getRefreshToken() // 假设你有一个方法来获取或存储 refresh_token ]; $options = [ 'http' => [ 'header' => "Content-type: application/x-www-form-urlencoded\r\n", 'method' => 'POST', 'content' => http_build_query($data), ], ]; $context = stream_context_create($options); $result = file_get_contents($url, false, $context); if ($result === FALSE) { throw new Exception("Error occurred during refreshing access token."); } $response = json_decode($result, true); if (!isset($response['access_token']) || !isset($response['expires_in'])) { throw new Exception("Invalid response received."); } $this->accessToken = $response['access_token']; $this->tokenExpires = time() + $response['expires_in']; } // 获取有效的 access_token private function getValidAccessToken() { if (!isset($this->accessToken) || time() > $this->tokenExpires) { // 在这里,你可能需要处理获取新的授权码或刷新令牌的逻辑 // 假设我们有一个授权码 $code = 'your_authorization_code_here'; // 你需要获取或存储这个值 $this->getNewAccessToken($code); } return $this->accessToken; } // 调用API public function callApi($endpoint, $data = []) { $url = $this->apiUrl . $endpoint; $headers = [ 'Authorization: Bearer ' . $this->getValidAccessToken(), 'Content-Type: application/json' ]; $options = [ 'http' => [ 'header' => implode("\r\n", $headers), 'method' => 'POST', 'content' => json_encode($data), ], ]; $context = stream_context_create($options); $result = file_get_contents($url, false, $context); if ($result === FALSE) { // 如果失败,检查是否是 token 过期,并尝试刷新 try { $this->refreshAccessToken(); $headers[0] = 'Authorization: Bearer ' . $this->accessToken; $options['http']['header'] = implode("\r\n", $headers); $context = stream_context_create($options); $result = file_get_contents($url, false, $context); } catch (Exception $e) { throw new Exception("API call failed: " . $e->getMessage()); } } return json_decode($result, true); }
} // 使用示例
$clientId = 'your_client_id';
$clientSecret = 'your_client_secret';
$redirectUri = 'your_redirect_uri';
$tokenUrl = 'https://api.example.com/oauth/token';
$apiUrl = 'https://api.example.com/v1/'; $apiClient = new ApiClient($clientId, $clientSecret, $redirectUri, $tokenUrl, $apiUrl); try { $response = $apiClient->callApi('endpoint', ['param1' => 'value1']); print_r($response);
} catch (Exception $e) { echo "Error: " . $e->getMessage();
}
注意:
- 示例代码中的
getNewAccessToken
方法假设你有一个授权码(code
)来获取access_token
。在实际应用中,你可能需要处理重定向和获取授权码的逻辑。 refreshAccessToken
方法假设你有一个refresh_token
来刷新access_token
。这取决于API提供者的实现。- 示例代码中的错误处理是基本的,你可能需要根据实际需求进行扩展。