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

PHP cURL请求OAuth2令牌遇Nginx 401错误的排查方案

解决OAuth2令牌请求返回401的问题

首先明确:401 Unauthorized错误基本和跨域无关——跨域问题(CORS)在浏览器端会有明确的控制台报错,且服务器通常不会返回401作为跨域的响应码。你的问题大概率是认证参数配置错误或者请求格式不匹配,下面一步步排查并修正:

1. 检查Nginx HTTP认证的类型匹配

你当前用了CURLAUTH_DIGEST,但Nginx的htpwd(即htpasswd)默认是Basic认证,而非Digest。如果Nginx配置的是Basic auth,这个参数会导致curl无法正确完成服务器要求的认证流程,直接返回401。

修正:把CURLAUTH_DIGEST换成CURLAUTH_BASIC,或者更灵活的CURLAUTH_ANY(让curl自动适配服务器要求的认证类型):

curl_setopt($curl_session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);

2. 修复请求体的格式不匹配问题

你设置了Content-Type: application/json,但CURLOPT_POSTFIELDS传的是数组——curl会自动把数组编码成application/x-www-form-urlencoded格式,和你声明的Content-Type冲突,导致OAuth2服务器无法解析grant_type等核心参数,最终返回401。

修正:把POST参数转成JSON字符串,同时确保Content-Type头正确:

$post_data = json_encode([
    'grant_type' => 'password',
    'username' => 'api_user',
    'password' => 'api_pwd'
]);
curl_setopt($curl_session, CURLOPT_POSTFIELDS, $post_data);

3. 验证OAuth2 Basic Auth头的正确性

确保base64_encode('api_client_id:api_secret')的结果没有问题:

  • 不要在api_client_id或api_secret前后加空格
  • 可以手动在终端验证编码结果:echo -n 'api_client_id:api_secret' | base64,和代码生成的对比是否一致

4. 确认Nginx的htpwd配置有效性

  • 检查htpwd_user和htpwd_pwd是否和Nginx配置的.htpasswd文件中的用户名密码一致
  • 确认Nginx的auth_basic指令确实应用在了/api/oauth/v1/token这个路径上

修正后的完整代码

$base64_encoded_client_id_and_secret = base64_encode('api_client_id:api_secret');
$curl_session = curl_init();

// 目标API地址
curl_setopt($curl_session, CURLOPT_URL, 'https://abcd/api/oauth/v1/token');

// 请求头:JSON格式 + OAuth2 Basic Auth
curl_setopt($curl_session, CURLOPT_HTTPHEADER, [
    'Content-Type: application/json',
    'Authorization: Basic ' . $base64_encoded_client_id_and_secret
]);

// Nginx的Basic认证(替换为实际的用户名密码)
curl_setopt($curl_session, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl_session, CURLOPT_USERPWD, "htpwd_user:htpwd_pwd");

// POST请求 + JSON格式的请求体
curl_setopt($curl_session, CURLOPT_POST, true);
$post_data = json_encode([
    'grant_type' => 'password',
    'username' => 'api_user',
    'password' => 'api_pwd'
]);
curl_setopt($curl_session, CURLOPT_POSTFIELDS, $post_data);

// 执行请求并解析结果(加上CURLOPT_RETURNTRANSFER避免直接输出响应)
curl_setopt($curl_session, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl_session);
if(curl_errno($curl_session)){
    echo 'CURL错误:' . curl_error($curl_session);
}
$ret = json_decode($response);

curl_close($curl_session);

额外排查技巧

如果还是返回401,可以开启curl的调试模式,查看请求的详细过程,定位问题:

curl_setopt($curl_session, CURLOPT_VERBOSE, true);

内容的提问来源于stack exchange,提问作者JarsOfJam-Scheduler

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 15:07:56