Zoho Mail API报错Invalid OAuth Scope:Scope不存在问题求助
解决Zoho Mail API「Invalid OAuth Scope Scope does not exist」错误
核心问题分析
1. 无效的OAuth Scope
你的授权URL中包含两个非Zoho官方定义的无效Scope:organization.accounts和accounts,这是触发错误的直接原因。Zoho的OAuth Scope必须严格遵循官方规范,比如Zoho Mail的Scope前缀为ZohoMail.,CRM的Scope前缀为ZohoCRM.。
2. PHP代码中的隐性错误
除了Scope问题,代码还存在三处关键错误,会导致后续API调用失败:
- POST参数拼接缺失
&,导致参数合并失效 - CURL句柄混淆,错误覆盖了其他请求的配置
- 错误使用ZUID作为Zoho Mail的账户ID(ZUID是用户全局ID,不是邮箱账户ID)
修复步骤
步骤1:修正授权URL的Scope
替换原授权URL中的Scope为合法值,移除无效的organization.accounts和accounts,保留必要的权限:
https://accounts.zoho.com/oauth/v2/auth?scope=ZohoMail.accounts.READ,ZohoMail.messages.READ,ZohoMail.messages.CREATE,ZohoMail.messages.UPDATE,ZohoCRM.users.READ&client_id=1000.Y6O7LWZG5UXXXXX42OMR0TUJE&response_type=code&access_type=offline&redirect_uri=https://example.com/callback.php
注意:如果免费版Zoho CRM不支持
ZohoCRM.users.READ,可暂时移除该Scope单独测试Mail API。
步骤2:修复PHP代码中的错误
以下是完整修复后的代码,标记了关键修改点:
<?php $grantToken = $_GET["code"]; $clientID = '1000.Y6O7LWXXXXXXXXMR0TUJE'; $clientSecret = '3edec1c3453XXXXXXXXXXXXXXX4e9dfcdd62bf62d6'; $refreshToken = '1000.a89707967c7166XXX993cde9e55c6.202e0d0b39ecd5XXX5f97527de0'; $redirectURI = 'https://example.com/callback.php'; // 获取Access Token $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://accounts.zoho.com/oauth/v2/token"); curl_setopt($ch, CURLOPT_POST, 1); // 修复:refresh_token后添加&,避免参数合并 curl_setopt($ch, CURLOPT_POSTFIELDS, "refresh_token=".$refreshToken."&grant_type=authorization_code&client_id=".$clientID."&client_secret=".$clientSecret."&redirect_uri=".$redirectURI."&code=".$grantToken); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); if (curl_errno($ch)) { echo 'Error:' . curl_error($ch); } curl_close ($ch); $response = json_decode($response, true); if (isset($response['error'])) { die('Token Error: ' . $response['error_description']); } $accessToken = $response['access_token']; $refreshToken = $response['refresh_token'] ?? $refreshToken; // 保留新的refresh_token(如果返回) print_r($response); echo '<br>Access Token: ' . $accessToken . '<br>'; $senderAddress = 'my@email.com'; // 获取用户信息(可选,用于验证) $ch2 = curl_init(); curl_setopt($ch2, CURLOPT_URL, "https://accounts.zoho.com/oauth/user/info"); curl_setopt($ch2, CURLOPT_RETURNTRANSFER, 1); // 修复:使用正确的句柄$ch2,而非$ch curl_setopt($ch2, CURLOPT_CUSTOMREQUEST, 'GET'); $headers = array(); $headers[] = "Authorization: Zoho-oauthtoken ".$accessToken; curl_setopt($ch2, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch2); if (curl_errno($ch2)) { echo 'Error:' . curl_error($ch2); } curl_close ($ch2); echo "User Info:<br>"; print_r($result); // 修复:正确获取Zoho Mail账户ID(不是ZUID) $ch3 = curl_init(); curl_setopt($ch3, CURLOPT_URL, "https://mail.zoho.com/api/accounts"); curl_setopt($ch3, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch3, CURLOPT_CUSTOMREQUEST, 'GET'); $headers = array(); $headers[] = "Authorization: Zoho-oauthtoken ".$accessToken; curl_setopt($ch3, CURLOPT_HTTPHEADER, $headers); $mailAccounts = curl_exec($ch3); if (curl_errno($ch3)) { echo 'Mail Account Error:' . curl_error($ch3); } curl_close($ch3); $mailAccounts = json_decode($mailAccounts, true); if (isset($mailAccounts['error'])) { die('Mail API Error: ' . $mailAccounts['message']); } // 取第一个邮箱账户ID(若有多个账户可按需选择) $accountId = $mailAccounts['data'][0]['accountId']; echo '<br>Mail Account ID: ' . $accountId . '<br>'; // 调用邮件搜索API $ch4 = curl_init(); curl_setopt($ch4, CURLOPT_URL, "https://mail.zoho.com/api/accounts/$accountId/messages/search?query=from:'".$senderAddress."'"); curl_setopt($ch4, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch4, CURLOPT_CUSTOMREQUEST, 'GET'); $headers = array(); $headers[] = "Authorization: Zoho-oauthtoken ".$accessToken; curl_setopt($ch4, CURLOPT_HTTPHEADER, $headers); $result = curl_exec($ch4); if (curl_errno($ch4)) { echo 'Error:' . curl_error($ch4); } curl_close ($ch4); echo '<br>Search Result:<br>'; print_r($result); ?>
额外注意事项
- 免费版权限限制:部分高级Scope(如
ZohoMail.messages.CREATE/UPDATE)可能在Zoho Mail免费版中不可用,若仍报错可尝试仅保留ZohoMail.accounts.READ和ZohoMail.messages.READ测试。 - 区域域名:如果你的Zoho账户属于非国际区(如.cn/.eu),需将API域名替换为对应区域的地址(例如
accounts.zoho.cn/mail.zoho.cn)。 - Refresh Token使用:当使用
authorization_code授权类型时,若已存在有效的refresh_token,可直接使用grant_type=refresh_token获取新的access_token,无需重复传入code。
内容的提问来源于stack exchange,提问作者Yehuda Clinton
相关产品推荐
相关产品推荐

