谷歌GCM服务器返回未授权错误401。

30

我正在使用GCM服务从服务器推送信息。如果我使用浏览器密钥,则显示成功消息为:{"multicast_id":4849013215736515938,"success":1,"failure":0,"canonical_ids":0,"results":[{"message_id":"0:1348742583011905%2adac3a0f9fd7ecd"}]},但是设备上没有收到任何通知。 如果我使用服务器密钥,则显示未授权错误401。我的代码如下:

$apiKey = "xxxxx";
$registrationIDs = array("xxxxxxxx");
$message = "testing Process";
$url = 'https://android.googleapis.com/gcm/send';
$fields = array(
        'registration_ids'  => $registrationIDs,
        'data'              => array("message"=>$message),
        );
$headers = array( 
        'Authorization: key=' . $apiKey,
        'Content-Type: application/json'
        );
$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, $url );
curl_setopt( $ch, CURLOPT_POST, true );
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt ($ch, CURLOPT_SSL_VERIFYPEER, 0); 
curl_setopt( $ch, CURLOPT_POSTFIELDS, json_encode($fields) );

$result = curl_exec($ch);
if(curl_errno($ch)){ echo 'Curl error: ' . curl_error($ch); }
curl_close($ch);
echo $result;

请帮我解决这个问题。谢谢您提前。


请参考以下链接:https://dev59.com/M3bZa4cB1Zd3GeqPI7Vh#21628030 - appukrb
你能否列出一份谷歌配置的小步骤清单? - valeriocomo
对于那些正在浏览的人,如果您突然开始遇到此错误而没有进行任何特定更改(服务器密钥仍相同),则可能需要将项目导入Firebase。请参见我的答案这里 - AL.
14个回答

31

您是否将服务器的 IP 添加到白名单中?这对于浏览器密钥不是默认必需的,但对于服务器密钥来说是必须的。

您可以在此处进行检查:

https://code.google.com/apis/console/#project:[YOUR PROJECT NUMBER]:access


3
谢谢大家。我之前遇到了浏览器密钥和API密钥的问题,现在使用服务器API密钥解决了这个问题,一切正常运行。 - Sushil Kandola
你好Jos。我该如何将我的服务器IP加入白名单?我一直收到未经授权的401错误提示。 - Olkunmustafa
2
谷歌更新了控制台,您将通过我的回答中的链接进行重定向。您可以在那里看到“允许编辑IP”的按钮。为了保证安全,根据我的密钥机密性,我已经将其设置为“允许任何IP”。 - Jos

19

另一个答案已经建议允许IP地址,这似乎很明显。对我有用的是将IPv6地址列入白名单。那就是关键!希望这能帮助其他人。


5
如果你正在使用curl进行调试,并且已经将你的IPv4地址加入白名单,但是没有加入IPv6地址,那么你可以传递"-4"参数给curl,以便它使用IPv4连接。 - John Mellor
1
更具体地说,添加此curl选项:curl_setopt($ch,CURLOPT_IPRESOLVE,CURL_IPRESOLVE_V4); - zeusstl
IPv6中0.0.0.0/0(所有IPv4地址)的等效表示是::/0,供您参考。 - four43

14

我尝试了这个帖子中的所有方法,但仍然没有成功。

所以我检查了已启用的API(API和认证-> API,已启用的API),并意识到我已经启用了Google Cloud Messaging for Chrome而不是Google Cloud Messaging for Android。一旦我启用了后者,它立即开始工作。

请确保你启用了正确的API!


这是一个好的解决方案!!! 运行得非常好。为Chrome创建Google Cloud消息传递就解决了问题。谢谢 :) - Adae Rodríguez

3

正如许多人所述,您需要将服务器的IPV4和IPV6添加到白名单中。如果您只想使用IPV4,请将以下内容添加到您的curl php init中:

curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );

2
我曾经把它放在了

标签中


$apiKey = "xxxxx"

比如我在 Android 客户端应用中添加了项目编号(project id),但是我错了,实际上服务器需要的是来自 Google 云控制台的 AppKey(你在那里激活适用于 Android 的 Google 云消息传递)。

    ProjectXXX -> APIs & auth -> Registered Apps -> Web App -> Server Key
 -> Api key

在我的情况下,我在“Web”平台上有一个名为“Service Account-project”的默认项目,但只有“Hosted Application section”,没有任何API密钥的证据。但当我创建名为“My app”的新“Web应用程序”时,它包含4个部分:OAuth 2.0客户端ID、证书、服务器密钥、浏览器密钥,我终于找到了API密钥;-)。
也许只有我不知道,但我相信这个答案也可以帮助其他人。

嘿m1uan,由于API密钥错误,出现了错误,现在已经修复好了 :) - Sushil Kandola
很高兴听到你的消息,我很愿意提供帮助;-) - m1uan

2

这就是我的问题所在,我试图使用服务器密钥而不是浏览器密钥,我想这更像 Curl 更像一个 Web 浏览器而不是直接的套接字连接。真不敢相信我浪费了多少时间,除了这个之外什么都试过了 /facepalm - CTS_AE

1
对我来说,问题在于您需要启用API。仅设置API是不够的。请检查“API管理”中的“启用的API”,确保“适用于Android的Google云消息传递”已启用。
如果没有启用,请单击“API库”选项卡并启用它。

0
看了一下代码,我认出这是从一个在网上发布的php-gcm示例中获取的。它非常好,并且我可以向您保证,浏览器密钥和白名单IP(不是IPV6或bas64 apikey)都可以使用。
没有显示任何消息的原因是因为您正在使用的发送通知函数'data' => array("message"=>$message)针对的是“message”键,这就是您必须传递给待处理意图的内容。
notification.setLatestEventInfo(context, title, message, intent);

这将使意图阅读包含在此键下的消息。消息本身是从下面粘贴的GCMIntentService方法中获取的:

 @Override
protected void onMessage(Context context, Intent intent) {
    Log.i(TAG, "Received message");
    String message = intent.getExtras().getString("message");
    Log.d(TAG, "The intent contains: " + intent.getExtras());
    displayMessage(context, message);
    // notifies user
    generateNotification(context, message);
}

0
这是问题所在:我使用了两个服务器,一个是staging服务器,另一个是生产服务器。对于我的staging服务器,它是由digital ocean托管的,我在服务器应用密钥允许的IP地址中输入了inet地址,这样它就可以正常工作。
然而,当我改为使用我的生产服务器的inet地址时,它失败了。相反,我必须使用inet6 addr: /64 Scope:Global才能使其工作。如果您遇到相同的问题,请输入ifconfig,找到上面的条目并输入允许的IP地址,那么它将正常工作。

0
你必须要创建一个不同于默认项目的项目,并且创建一个密钥。不要使用默认项目。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接