отправка push-уведомлений и получение неожиданного кода ответа: 401 и 403 - PullRequest
0 голосов
/ 20 июня 2019

Я использовал web push api для отправки уведомлений подписчикам, используя javascript и c # в веб-формах asp.net. Для подписки я использовал методtification.permission и сервисный работник, когда пользователь разрешает, я сохраняю данные подписки в моей базе данных, которые включают открытый ключ, закрытый ключ, конечную точку, auth, p256dh.

для отправки уведомлений я создал службу, которая берет данные из базы данных и отправляет уведомления этим пользователям с помощью работника службы. проблема в том, что когда я отправляю уведомления 3000 пользователям, он успешно отправляет только 700, а остальные выдают ошибку Получен неожиданный код ответа: 403 Получен неожиданный код ответа: 401

Я искал эти ошибки, так как кажется, что это ошибка аутентификации b, но не смог найти, как ее избежать, так как все подписчики использовали один и тот же метод, но почему в основном не получилось, а несколько успешных?

https://github.com/web-push-libs/web-push-csharp

Я реализовал этот код в своем приложении для веб-форм asp.net.

createdevice.js file

Notification.requestPermission().then(function (status) {
    debugger;
    if (status === 'denied') {`enter code here`
        errorHandler('[Notification.requestPermission] Browser denied permissions to notification api.');
    } else if (status === 'granted') {

        console.log('[Notification.requestPermission] Initializing service worker.');
        debugger;
        initialiseServiceWorker();
        debugger;

            subscribe();




    }
});
debugger;

функция подписки ()

navigator.serviceWorker.ready.then(function (reg) {
    var subscribeParams = { userVisibleOnly: true };
    debugger;
    //Setting the public key of our VAPID key pair.
    var applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
    subscribeParams.applicationServerKey = applicationServerKey;
    reg.pushManager.subscribe(subscribeParams)
        .then(function (subscription) {
            debugger;
            isSubscribed = true;

            var p256dh = base64Encode(subscription.getKey('p256dh'));
            var auth = base64Encode(subscription.getKey('auth'));

            console.log(subscription);
            var endpoint = subscription.endpoint;

            var ajaxResult = $.ajax({
                method: "POST",
                url: "/index.aspx/saveCredentialsInDb",
                data: JSON.stringify({ endpoint: endpoint, p256dh: p256dh, auth: auth }),
                contentType: "application/json; charset=utf-8",
                dataType: "json",

            });
            ajaxResult.done(function (result) {
                debugger;
                if (result.d=="invalid") {
                    navigator.serviceWorker.ready.then(function (reg) {
                        debugger;
                        reg.pushManager.getSubscription().then(function (subscription) {
                            debugger;
                            subscription.unsubscribe().then(function (successful) {
                                debugger;
                                // You've successfully unsubscribed

                                window.location = "http://localhost:59290/redirected_page.aspx";
                                return;

                            }).catch(function (e) {
                            })
                        })
                    });
                }
                else if (result.d == "OK") {
                console.log("Data Stored " + result.d + " ");
                $('#PushEndpoint').val(subscription.endpoint);
                $('#PushP256DH').val(p256dh);
                $('#PushAuth').val(auth);
            }
            });

        })
        .catch(function (e) {
            errorHandler('[subscribe] Unable to subscribe to push', e);
        });

});

sw.js

self.addEventListener ('push', функция (событие)

debugger;
var data = {};
if (event.data) {
    data = event.data.json();
}

console.log('Notification Received1:');
console.log(data);

var title = data.Title;
var message = data.Message;
var img = data.Image;`enter code here`
var image1 = "images/TBGWT-Sitcom-Final-1600px.png";
var icon = "images/push-icon.jpg";
var url = "https://google.com/";

const title1 = 'Actions Notification';
const options = {
    body: message,
    image: image1,
    data: url,
    requireInteraction: true,
    actions: [
      {
          action: 'close-action',
          title: 'Close',
          icon: 'images/multiply.png'
      }

    ]
};

event.waitUntil(self.registration.showNotification(title1, options ));

Файл index.aspx:

<script src="sw1.js"></script>
<script src="js/CreateDevice.js"></script>

<input id="PushEndpoint" runat="server" />
<input id="PushP256DH" runat="server"/>
<input id="PushAuth" runat="server"/>

<form id="form1" runat="server">
<div>
<asp:Button ID="send_notification" Text="Send Notification" runat="server" OnClick="send_notification_Click"/>

     <button id="unsub">Unsub</button>
</div>
</form>

index.aspx.cs

public partial class index : System.Web.UI.Page
{
    public string FromServer;
    public static string publicKey;
    public static string privateKey;
    protected void Page_Load(object sender, EventArgs e)
    {
        var keys = VapidHelper.GenerateVapidKeys();
        FromServer = keys.PublicKey;
        publicKey = keys.PublicKey;
        privateKey = keys.PrivateKey;
        StringBuilder strScript = new StringBuilder();

        strScript.Append("<script type=\"text/javascript\">");

        strScript.Append("var applicationServerPublicKey='");

        strScript.Append(FromServer);

        strScript.Append("';");

        strScript.Append("</script>");



        ClientScriptManager script = Page.ClientScript;



        if (!script.IsClientScriptBlockRegistered(this.GetType(), "Var"))

        {

            script.RegisterClientScriptBlock(this.GetType(), "Var", strScript.ToString());

        }

    }
    [WebMethod]
    public static string saveCredentialsInDb(string endpoint, string p256dh, string auth)
    {
        var _publicKey = publicKey;
        var _privateKey = privateKey;
        var isError = false;
        string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
        string query = @"INSERT INTO userCredentials (PublicKey, PrivateKey, [Endpoint], Auth, p256dh)
                        VALUES (@PublicKey, @PrivateKey, @Endpoint, @Auth, @p256dh)";

        // create connection and command
         SqlConnection cn = new SqlConnection(conStr);
            using (SqlCommand cmd = new SqlCommand(query, cn))
            {
                // define parameters and their values
                cmd.Parameters.AddWithValue("@PublicKey", _publicKey);
                cmd.Parameters.AddWithValue("@PrivateKey", _privateKey);
                cmd.Parameters.AddWithValue("@Endpoint", endpoint);
                cmd.Parameters.AddWithValue("@Auth", auth);
                cmd.Parameters.AddWithValue("@p256dh", p256dh);
                // open connection, execute INSERT, close connection
                cn.Open();
            //if (isError == false)
            //{
                cmd.ExecuteNonQuery();
            //}
                cn.Close();
            }
        //if (isError == true)
        //{
        //    return "invalid";
        //}
        //else
        //{
            return "OK";
        //}

    }
    public class Data
    {
        [JsonProperty("Title")]
        public string Title { get; set; }
        [JsonProperty("Message")]
        public string Message { get; set; }
        [JsonProperty("Image")]
        public string Image { get; set; }

    }
    public class TimeToLive
    {

        public int Num { get; set; }

    }

    protected void send_notification_Click(object sender, EventArgs e)
    {
        DataTable dt = new DataTable();
        string message = "";
        string title = "";
        byte[] image = new byte[] { };
        string publicKey1 = "";
        string privateKey1 = "";
        string endpoint = "";
        string auth = "";
        string p256dh = "";
        string base64image = "";
        List<string> listData = new List<string>();
        string conStr = ConfigurationManager.ConnectionStrings["sqlConString"].ConnectionString;
        string query = @"SELECT * from userCredentials, [Payload]";

        // create connection and command
        SqlConnection cn = new SqlConnection(conStr);
        using (SqlCommand cmd = new SqlCommand(query, cn))
        {
            // define parameters and their values

            // open connection, execute INSERT, close connection
            cn.Open();
            SqlDataAdapter da = new SqlDataAdapter(cmd);
            // this will query your database and return the result to your datatable
            da.Fill(dt);
            cn.Close();
        }
        Data body = new Data();

        foreach (DataRow row in dt.Rows)
        {

            //message = row["Message"].ToString();
            //title = row["Title"].ToString();
            publicKey1 = row["PublicKey"].ToString();
            privateKey1 = row["PrivateKey"].ToString();
            endpoint = row["Endpoint"].ToString();
            auth = row["Auth"].ToString();
            p256dh = row["p256dh"].ToString();
            message = row["Message"].ToString();
            title = row["Title"].ToString();
            //string strfn = Convert.ToString(DateTime.Now.ToFileTime());
            //FileStream fs = new FileStream(strfn,
            //                  FileMode.CreateNew, FileAccess.Write);
            //fs.Write(Bimage, 0, Bimage.Length);
            //fs.Flush();
            //fs.Close();
            // FromFile(strfn);

            //image = "data:images/png;base64,"+ base64image;

        }
        //listData.Add(title);
        //listData.Add(message);
        body.Title = title;
        body.Message = message;
        //body.Image = base64image.ToString(); 
        var payload = JsonConvert.SerializeObject(body);

    var pushSubscription = new PushSubscription(endpoint, p256dh, auth);
            //var vapidDetails = new VapidDetails("mailto:example@example.com", publicKey1, privateKey1);
        var options = new Dictionary<string, object>();
        options["vapidDetails"] = new VapidDetails("mailto:example@example.com", publicKey1, privateKey1);
        //TimeToLive ttl = new TimeToLive();
        //ttl.Num = 3600;
        //options["TTL"] = 3600;

        var webPushClient = new WebPushClient();
        try
        {
            webPushClient.SendNotificationAsync(pushSubscription, payload, options);
        }
        catch (WebPushException ex)
        {
            throw ex;
        }


    }
}

при отправке 3000 подписчикам отправляет 700, а остальным из них не удалось и выдает ошибку в файле index.aspx.cs по адресу:

webPushClient.SendNotificationAsync (pushSubscription, полезная нагрузка, параметры);

Получен неожиданный код ответа: 401 Получен неожиданный код ответа: 403

Остальная часть кода предназначена для понимания того, что происходит на стороне клиента и как я это реализовал.

...