You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用OAuth 2.0仅应用认证调用X API发帖时出现权限错误

问题分析与解决:X平台发布推文认证失败

问题描述

用户编写了以下PHP+cURL代码尝试发布推文:

$api_key='xx';
$api_secret='yy';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.twitter.com/oauth2/token');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Content-Type: application/x-www-form-urlencoded',
]);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, $api_key.':'.$api_secret);
curl_setopt($ch, CURLOPT_POSTFIELDS, 'grant_type=client_credentials');

$response = curl_exec($ch);

curl_close($ch);

$response=json_decode($response);
$access_token=$response->access_token;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.twitter.com/2/tweets');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer '.$access_token,
    'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"text":"Hello, world!"}');

$response = curl_exec($ch);

curl_close($ch);

print_r($response);

成功获取access_token后,收到错误提示:

"Authenticating with OAuth 2.0 Application-Only is forbidden for this endpoint. Supported authentication types are [OAuth 1.0a User Context, OAuth 2.0 User Context]"

错误原因

你使用的是OAuth 2.0应用级认证(Application-Only),这种认证仅适用于无需绑定具体用户的操作(比如搜索公开推文、查看用户公开信息),但发布推文属于必须关联具体用户账号的操作,必须使用带用户上下文的认证方式:

  • OAuth 1.0a 用户上下文
  • OAuth 2.0 用户上下文(需通过用户授权流程获取的Access Token,而非应用自身凭证生成的token)

解决方案

方式1:使用OAuth 1.0a用户上下文认证

需提前通过用户授权流程获取用户的access_token和access_token_secret,代码示例如下:

$api_key = 'xx';
$api_secret = 'yy';
$user_access_token = '用户授权的access_token';
$user_access_token_secret = '用户授权的access_token_secret';

$url = 'https://api.twitter.com/2/tweets';
$method = 'POST';
$post_data = json_encode(['text' => 'Hello, world!']);

// 构建OAuth参数
$oauth_params = [
    'oauth_consumer_key' => $api_key,
    'oauth_nonce' => md5(uniqid(rand(), true)),
    'oauth_signature_method' => 'HMAC-SHA1',
    'oauth_timestamp' => time(),
    'oauth_token' => $user_access_token,
    'oauth_version' => '1.0'
];

// 生成签名
$base_string = $method . '&' . rawurlencode($url) . '&' . rawurlencode(http_build_query($oauth_params));
$signing_key = rawurlencode($api_secret) . '&' . rawurlencode($user_access_token_secret);
$oauth_params['oauth_signature'] = base64_encode(hash_hmac('sha1', $base_string, $signing_key, true));

// 构建Authorization头
$auth_header = 'OAuth ';
foreach ($oauth_params as $key => $value) {
    $auth_header .= rawurlencode($key) . '="' . rawurlencode($value) . '", ';
}
$auth_header = rtrim($auth_header, ', ');

// 发送请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    $auth_header,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);

$response = curl_exec($ch);
curl_close($ch);

print_r($response);

方式2:使用OAuth 2.0用户上下文认证

需先通过OAuth授权码流程获取带tweet.write权限的用户级access_token,然后直接调用API:

$user_access_token = '用户授权的带write权限的OAuth2 access_token';

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.twitter.com/2/tweets');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $user_access_token,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"text":"Hello, world!"}');

$response = curl_exec($ch);
curl_close($ch);

print_r($response);

注意事项

  • 用户授权流程需在X开发者平台配置回调地址,引导用户完成授权后获取对应token
  • 确保应用已在X开发者平台申请并开启tweet.write权限

内容的提问来源于stack exchange,提问作者vespino

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 20:45:10