首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >用于防火墙云消息传递的服务器密钥的Base64编码

用于防火墙云消息传递的服务器密钥的Base64编码
EN

Stack Overflow用户
提问于 2016-12-27 02:12:32
回答 2查看 6.8K关注 0票数 10

从三天以来,我一直困在这个问题上,搜索了谷歌,但没有成功。我遵循了推送通知示例中的指令。但是当我试图实现它时,我会遇到这个严重的错误。

代码语言:javascript
运行
复制
Uncaught (in promise) DOMException: Failed to execute 'atob' on 'Window': The string to be decoded is not correctly encoded.

我发现在Base64字符串中不允许冒号(:),但是在选项卡的Firebase中给出的服务器键是

代码语言:javascript
运行
复制
AAAA-8MWvk0:APA91bHmU8XL-rzOn9SPbpG98NSqAJcuhYBBh7oze_XhprBpK7Q9PPWm3PwBo6Llxby4zjhVtgvKPIaSAQGp-8RfMV10_d1GekzICrVX9oYO8pi6dOM4VTp52CCAzug6NYIa10tNddsgE2P5QowGAYcnRHxLkrHXsw

它包含一个冒号(别担心,它只是一个测试应用程序,所以没有隐私问题)。

当我试图使用遗留服务器密钥时,它只是抛出一个错误。我也尝试使用Firebase中提供的其他密钥,但没有成功。请告诉我实际使用哪个服务器密钥以及如何使用?

我正在附加我的代码片段,它实际上执行推送订阅。

代码语言:javascript
运行
复制
 const API_KEY = "AIzaSyByIOl-mW0pu8SEXFeutB8jq59hhiau0wI";
 var GCM_ENDPOINT = 'https://fcm.googleapis.com/fcm/send';
 const legacy  = 'AIzaSyDGF8t125bJ4wBvYn_UdRewkTxHGr7KpH8';
 const applicationServerPublicKey = 'AAAA-8MWvk0APA91bHmU8XL-rzOn9SPbpG98NSqAJcuhYBBh7oze_XhprBpK7Q9PPWm3PwBo6Llxby4zjhVtgvKPIaSAQGp-8RfMV10_d1GekzICrVX9oYO8pi6dOM4VTp52CCAzug6NYIa10tNddsgE2P5QowGAYcnRHxLkrHXsw';

function urlB64ToUint8Array(base64String) {
 const padding = '='.repeat((4 - base64String.length % 4) % 4);
 const base64 = (base64String + padding)
 .replace(/\-/g, '+')
 .replace(/_/g, '/');
 console.log(base64);
 const rawData = window.atob(base64);
 console.log(rawData);
 const outputArray = new Uint8Array(rawData.length);

 for (let i = 0; i < rawData.length; ++i) {
  outputArray[i] = rawData.charCodeAt(i);
 }
 return outputArray;
}

function endpointWorkaround(pushSubscription) {
 // Make sure we only mess with GCM
 if(pushSubscription.endpoint.indexOf('https://fcm.googleapis.com/fcm/send') !== 0) {
  return pushSubscription.endpoint;
 }

 var mergedEndpoint = pushSubscription.endpoint;
 // Chrome 42 + 43 will not have the subscriptionId attached
 // to the endpoint.
 if (pushSubscription.subscriptionId &&
 pushSubscription.endpoint.indexOf(pushSubscription.subscriptionId) === -1)    {
  // Handle version 42 where you have separate subId and Endpoint
  mergedEndpoint = pushSubscription.endpoint + '/' +
  pushSubscription.subscriptionId;
 }
 return mergedEndpoint;
}

function sendSubscriptionToServer(subscription) {
 // TODO: Send the subscription.endpoint
 // to your server and save it to send a
 // push message at a later date
 //
 // For compatibly of Chrome 43, get the endpoint via
 // endpointWorkaround(subscription)
 console.log('TODO: Implement sendSubscriptionToServer()',    JSON.stringify(subscription));

 var mergedEndpoint = endpointWorkaround(subscription);

 // This is just for demo purposes / an easy to test by
 // generating the appropriate cURL command
 var temp = showCurlCommand(mergedEndpoint);
 return temp;
}

// NOTE: This code is only suitable for GCM endpoints,
// When another browser has a working version, alter
// this to send a PUSH request directly to the endpoint
function showCurlCommand(mergedEndpoint) {
 // The curl command to trigger a push message straight from GCM
 if (mergedEndpoint.indexOf(GCM_ENDPOINT) !== 0) {
  console.warn('This browser isn\'t currently ' + 'supported for this demo');
  return;
 }

 var endpointSections = mergedEndpoint.split('/');
 var subscriptionId = endpointSections[endpointSections.length - 1];

 var curlCommand = 'curl --header "Authorization: key=' + API_KEY + '" --header Content-Type:"application/json" ' + GCM_ENDPOINT + ' -d "{\\"registration_ids\\":[\\"' + subscriptionId + '\\"]}"';

 console.log(curlCommand);
 return subscriptionId;
}

function initialiseState() {
 // Are Notifications supported in the service worker?
 if (!('showNotification' in ServiceWorkerRegistration.prototype)) {
  console.warn('Notifications aren\'t supported.');
  return;
 }

 // Check the current Notification permission.
 // If its denied, it's a permanent block until the
 // user changes the permission
 if (Notification.permission === 'denied') {
  console.warn('The user has blocked notifications.');
  return;
 }

 // Check if push messaging is supported
 if (!('PushManager' in window)) {
  console.warn('Push messaging isn\'t supported.');
  return;
 }
 var prom = new Promise(function(resolve, reject) {
  navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
    // Do we already have a push message subscription?
serviceWorkerRegistration.pushManager.getSubscription().then(function(subscription) {
            // Enable any UI which subscribes / unsubscribes from
            // push messages.
            // var pushButton = document.querySelector('.js-push-button');
            // pushButton.disabled = false;

            if (!subscription) {
                // We aren’t subscribed to push, so set UI
                // to allow the user to enable push
        subscribe();
                return;
            }

            // Keep your server in sync with the latest subscription
      var temp = sendSubscriptionToServer(subscription);
      if(temp){
        resolve(temp);
      }else{
        reject("Oops!")
      }

            // Set your UI to show they have subscribed for
            // push messages
            // pushButton.textContent = 'Disable Push Messages';
            // isPushEnabled = true;
        })
        .catch(function(err) {
            console.error('Error during getSubscription()', err);
      reject(err);
        });
});
});
return prom;
}

function unsubscribe() {
 // var pushButton = document.querySelector('.js-push-button');
 // pushButton.disabled = true;

 navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
  // To unsubscribe from push messaging, you need get the
  // subcription object, which you can call unsubscribe() on.
  serviceWorkerRegistration.pushManager.getSubscription().then(
  function(pushSubscription) {
   // Check we have a subscription to unsubscribe
   if (!pushSubscription) {
    // No subscription object, so set the state
    // to allow the user to subscribe to push
    //  isPushEnabled = false;
    //  pushButton.disabled = false;
    //  pushButton.textContent = 'Enable Push Messages';
    return;
   }

   // TODO: Make a request to your server to remove
   // the users data from your data store so you
   // don't attempt to send them push messages anymore

   // We have a subcription, so call unsubscribe on it
   pushSubscription.unsubscribe().then(function() {
    //  pushButton.disabled = false;
    //  pushButton.textContent = 'Enable Push Messages';
    //  isPushEnabled = false;
   }).catch(function(e) {
     // We failed to unsubscribe, this can lead to
     // an unusual state, so may be best to remove
     // the subscription id from your data store and
     // inform the user that you disabled push

     console.log('Unsubscription error: ', e);
     //  pushButton.disabled = false;
   });
 }).catch(function(e) {
   console.error('Error thrown while unsubscribing from ' + 'push messaging.', e);
 });
});
}

function subscribe() {
 // Disable the button so it can't be changed while
 // we process the permission request
 // var pushButton = document.querySelector('.js-push-button');
 // pushButton.disabled = true;

 navigator.serviceWorker.ready.then(function(serviceWorkerRegistration) {
  const applicationServerKey = urlB64ToUint8Array(applicationServerPublicKey);
  serviceWorkerRegistration.pushManager.subscribe({userVisibleOnly: true,  applicationServerKey: applicationServerKey})
 .then(function(subscription) {
  console.log(subscription);
  // The subscription was successful
  //  isPushEnabled = true;
  //  pushButton.textContent = 'Disable Push Messages';
  //  pushButton.disabled = false;

  // TODO: Send the subscription subscription.endpoint
  // to your server and save it to send a push message
  // at a later date
  return sendSubscriptionToServer(subscription);
 })
 .catch(function(e) {
  if (Notification.permission === 'denied') {
   // The user denied the notification permission which
   // means we failed to subscribe and the user will need
   // to manually change the notification permission to
   // subscribe to push messages
   console.log('Permission for Notifications was denied');
   //  pushButton.disabled = true;
  } else {
   // A problem occurred with the subscription, this can
   // often be down to an issue or lack of the gcm_sender_id
   // and / or gcm_user_visible_only
   console.log('Unable to subscribe to push.', e);
   //  pushButton.disabled = false;
   //  pushButton.textContent = 'Enable Push Messages';
  }
 });
});
}
EN

回答 2

Stack Overflow用户

发布于 2017-01-03 23:02:46

可悲的是,这是Chrome令人困惑的事情。

在最基本的层次上:网络推送完全独立于web的Firebase消息传递。

Web推送和应用服务器密钥

Web push需要一个应用服务器密钥,这就是您在服务工作人员推送管理器上传递给订阅调用的内容:

代码语言:javascript
运行
复制
pushManager.subscribe({userVisibleOnly: true, applicationServerKey: MY_KEY});

在网络推送中,applicationServerKey需要是一个Uint8Array (即65字节的数组)。这个密钥可以生成任何您喜欢,只是确保您保持私钥私钥,并使用您的web应用程序的公钥。

在我写的代码中,我指示您从:https://web-push-codelab.appspot.com/获得您的密钥

此页面动态生成一组应用程序服务器密钥,并将结果存储在本地存储中(因此您可以使用相同的页面发送推送消息-这需要应用程序服务器键)。

您也可以很容易地从像网络推送节点CLI这样的工具中获得密钥。

防火墙服务器密钥

用于web的Firebase消息传递SDK使用服务工作人员实现对web的推送,但它为您管理应用服务器密钥。原因是Firebase消息传递SDK将您设置为使用Firebase Cloud消息API来触发推送消息,而不是您需要在您正在执行的codelab中使用的Web push协议。

Firebase控制台中的"Server键“是触发推送消息时使用的键,它是”授权“头。

代码语言:javascript
运行
复制
https://fcm.googleapis.com/fcm/send
Content-Type: application/json
Authorization: key=<YOUR SERVER KEY HERE>

摘要

  • 有自己的SDK,如果您使用它,那么您应该遵循它的指南,并使用它的服务器端API。
  • Web (开放web标准)与Firebase (或任何其他推送服务)没有直接依赖关系,因此您可以创建特定格式的密钥,并使用web Push协议触发推送消息。(Chrome在幕后使用Firebase,但作为网站推送的开发人员,您不需要为Firebase做任何事情)。
票数 8
EN

Stack Overflow用户

发布于 2020-08-17 13:52:33

理解FCM推送服务和FCM Firebase产品之间的区别是很重要的。

FCM推送服务

  • 负责向chrome浏览器传递推送消息。推送消息到达铬浏览器的唯一途径是通过FCM push服务。
  • FCM服务位于mozilla推送服务旁边。每个浏览器都有自己的推送服务。
  • 推送服务实现web推送协议。push服务的Chrome浏览器组件向push服务的后端组件(后端组件与浏览器维护打开的HTTP2连接。 )发出请求,并使用HTTP2服务器推送向浏览器传递推送消息。
  • 在chrome上调用pushManager.subscribe()将为您提供表单https://fcm.googleapis.com/fcm/send/f4wa5jqguZI:APA91bEI0J6gtg3NYqdB_NhB-YWUPxYVdWkK25h0X2nRogeeMYW3INS71hqyAOG06bvyqwbGhukl9qiJJHU9IalxcfLOE47PN70qwKwcBgbDSEW-NFYkQqv3Uj-qANZT4zQ3kG76asdf的端点。

FCM火基产品

  • Firebase产品使用FCM服务向Chrome浏览器传递推送消息。不过,firebase产品可以与其他push服务和其他浏览器交互。firebase产品甚至可以通过不基于网络推送协议的APNS向ios应用程序发送推送消息。
  • 调用firebase.messaging().getToken()将为您提供表单eyFOxmzsVFGTwi80wpAcR8:APA91bEtIDf2SH4D1CNcQ2M3kX9-i5nHsbsTXcvO7UJaWteXQz7wxTxNvpmHewMpaMeXf90_BsAJblVpsVoQAUT-CIxTUAkJOr4X3LEp0SbK8E1_iRrpd55e5giP3-r3jDN0rxDuasdf的令牌(有时称为registrationID)。
票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41338179

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档