远程服务器返回错误:(401)未经授权的C#GCM响应

时间:2013-12-05 17:59:10

标签: android push-notification google-cloud-messaging unauthorized

我已经看到这个问题发布在一千个地方,我已经尝试了所有适用于其他人的解决方案,但我无法让这个为我工作。我使用这篇文章作为我使用的项目(Unauthorized when calling Google GCM)的基线。我已经尝试过API密钥和浏览器密钥,但没有成功。

这是我的代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Web;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

using System.IO;

namespace GCMTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            string BrowserAPIKey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxx";

            string message = "some test message";
            string tickerText = "example test GCM";
            string contentTitle = "content title GCM";
            string postData = "{ \"registration_ids\": [ \"" + txtRegistrationID.Text + "\" ], \"data\": {\"tickerText\":\"" + tickerText + "\", \"contentTitle\":\"" + contentTitle + "\", \"message\": \"" + message + "\"}}";

            string response = SendGCMNotification(BrowserAPIKey, postData);
        }

        private string SendGCMNotification(string apiKey, string postData, string postDataContentType = "application/json")
        {
            // from here:
            // https://stackoverflow.com/questions/11431261/unauthorized-when-calling-google-gcm
            //
            // original:
            // http://www.codeproject.com/Articles/339162/Android-push-notification-implementation-using-ASP

            ServicePointManager.ServerCertificateValidationCallback += new RemoteCertificateValidationCallback(ValidateServerCertificate);

            //
            //  MESSAGE CONTENT
            byte[] byteArray = Encoding.UTF8.GetBytes(postData);

            //
            //  CREATE REQUEST
            HttpWebRequest Request = (HttpWebRequest)WebRequest.Create("https://android.googleapis.com/gcm/send");

            Request.Method = "POST";
            Request.KeepAlive = false;
            Request.ContentType = postDataContentType;
            //Request.Headers.Add(string.Format("Authorization: key={0}", apiKey));
            Request.Headers.Add(HttpRequestHeader.Authorization, String.Format("key={0}", apiKey));
            Request.ContentLength = byteArray.Length;

            //Stream dataStream;
            try
            {
                Stream dataStream = Request.GetRequestStream();

                dataStream.Write(byteArray, 0, byteArray.Length);
                dataStream.Close();
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }

            //
            //  SEND MESSAGE
            try
            {
                WebResponse Response = Request.GetResponse();

                HttpStatusCode ResponseCode = ((HttpWebResponse)Response).StatusCode;

                if (ResponseCode.Equals(HttpStatusCode.Unauthorized) || ResponseCode.Equals(HttpStatusCode.Forbidden))
                {
                    MessageBox.Show("Unauthorized - need new token");

                }
                else if (!ResponseCode.Equals(HttpStatusCode.OK))
                {
                    MessageBox.Show("Response from web service isn't OK");
                }

                StreamReader Reader = new StreamReader(Response.GetResponseStream());
                string responseLine = Reader.ReadToEnd();
                Reader.Close();

                return responseLine;
            }
            catch (Exception e)
            {
                MessageBox.Show(e.Message);
            }
            return "error";
        }


        public static bool ValidateServerCertificate(
                                                  object sender,
                                                  X509Certificate certificate,
                                                  X509Chain chain,
                                                  SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }
    }

}

在这条线上犯了错误:

WebResponse Response = Request.GetResponse();

使用以下消息: “远程服务器返回错误:(401)未经授权。”

表单允许输入设备注册ID。如果我能够使其工作,它将被改变以在生产环境中更加可用。应用程序现在在我的本地计算机上运行,​​但最终将驻留在远程服务器上。

我能得到的任何帮助都会非常感激。我一直在阅读关于这个帖子的帖子已经有一个星期了,但我还是没有取得任何进展。我认为可能导致此问题的一件事是我在本地运行而不是在服务器上运行。此请求是否需要来自浏览器密钥中“referer”中列出的地址?

再次感谢!

2 个答案:

答案 0 :(得分:2)

如果您使用的是浏览器密钥,则应删除该密钥的allowed referrers,以便它显示Any referrer is allowed。这将允许您从本地运行的服务器发送通知。

否则,您只能从具有allowed referrers中指定的域的网站使用该浏览器密钥发送GCM消息。

答案 1 :(得分:0)

如果API“Google Cloud Messaging for Android”处于活动状态,请检查控制台(console.developers.google.com)。

我有同样的问题,我认为它是活跃的,不是