PHP中无需登录刷新Dropbox API访问令牌及获取长效令牌
解决Dropbox PHP SDK令牌过期自动刷新问题
核心思路
针对内部应用无需外部用户登录的场景,可通过OAuth 2.0离线授权模式获取refresh token,用它自动刷新过期的access token,实现无人值守的文件上传。
第一步:获取初始Refresh Token
- 登录Dropbox开发者控制台,进入目标应用的
Permissions页面,勾选所需权限(如files.content.write用于文件上传)。 - 切换到
Settings页面,在OAuth 2.0区域设置Redirect URI为你可访问的地址(如http://localhost/dropbox-callback.php),同时开启Offline access。 - 构造授权URL并在浏览器打开,登录内部Dropbox账号完成授权:
https://www.dropbox.com/oauth2/authorize?client_id=你的客户端ID&response_type=code&token_access_type=offline
- 授权后跳转至设置的地址,URL中会携带
code参数,用该参数兑换access token和refresh token:
$clientId = "你的客户端ID"; $clientSecret = "你的客户端密钥"; $code = "URL中获取的授权码"; $redirectUri = "你的回调地址"; $ch = curl_init("https://api.dropboxapi.com/oauth2/token"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ "code" => $code, "grant_type" => "authorization_code", "client_id" => $clientId, "client_secret" => $clientSecret, "redirect_uri" => $redirectUri ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $tokens = json_decode($response, true); // 将$tokens['access_token']和$tokens['refresh_token']存入数据库或安全配置文件
第二步:实现自动刷新令牌的上传逻辑
修改现有代码,加入令牌有效性校验与自动刷新逻辑:
include('dropbox/vendor/autoload.php'); // 从存储中读取令牌信息 $clientId = "你的客户端ID"; $clientSecret = "你的客户端密钥"; $accessToken = "存储的access token"; $refreshToken = "存储的refresh token"; // 初始化Dropbox客户端 $app = new DropboxApp($clientId, $clientSecret, $accessToken); $dropbox = new Dropbox($app); // 校验令牌有效性,过期则自动刷新 try { // 调用简单API验证令牌(如获取当前账号信息) $dropbox->getCurrentAccount(); } catch (DropboxClientException $e) { if (str_contains($e->getMessage(), "expired_access_token")) { // 发起令牌刷新请求 $ch = curl_init("https://api.dropboxapi.com/oauth2/token"); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query([ "grant_type" => "refresh_token", "client_id" => $clientId, "client_secret" => $clientSecret, "refresh_token" => $refreshToken ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch); $newTokens = json_decode($response, true); if (isset($newTokens['access_token'])) { // 更新存储的access token(refresh token长期有效,无需替换) $accessToken = $newTokens['access_token']; // 重新初始化客户端 $app = new DropboxApp($clientId, $clientSecret, $accessToken); $dropbox = new Dropbox($app); } else { throw new Exception("令牌刷新失败: " . $response); } } else { throw $e; } } // 执行文件上传逻辑 $data = []; // 从数据库获取待上传文件列表 if (!$data->isEmpty()) { foreach ($data as $list) { $filePath = 'folder_path/' . $list->file_name; $fileName = $list->file_name; try { $dropboxFile = new DropboxFile($filePath); $uploadedFile = $dropbox->upload($dropboxFile, "/folder_name/" . $fileName, ['autorename' => true]); echo $uploadedFile->getPathDisplay(); } catch (DropboxClientException $e) { print_r($e->getMessage()); } } }
注意事项
- 令牌存储:
refresh token需安全存储,避免泄露,它可长期用于获取新的access token。 - 权限校验:确保应用已配置足够的文件操作权限,否则上传会失败。
- 异常扩展:可补充网络异常、文件不存在等场景的处理逻辑,提升稳定性。
内容的提问来源于stack exchange,提问作者Yogesh Saroya
相关产品推荐
相关产品推荐

