我正在尝试在我的应用程序中通过网络推送协议(protocol)使用网络推送通知。为了将 Push API 与 VAPID 结合使用,我需要一个 applicationServerKey
。
PushManager subscribe
方法采用 VAPID key (仅公钥)作为参数,并提供订阅端点和推送消息的 key 。
为了生成 VAPID key ,到目前为止,我一直在使用 node.js(google web-push
包)和 openssl
。但在我的用例中,VAPID key 应该在 Java 中生成并传递给 JavaScript 以从浏览器订阅。
我正在尝试使用下面的 Java 代码来生成 VAPID key 。我能够成功创建 key ,但是当我传递生成的公钥(base64 编码字符串)时,subscribe
方法返回一个错误:
Unable to register service worker. DOMException: Failed to execute 'subscribe' on 'PushManager': The provided applicationServerKey is not valid..
请帮我解决这个问题。下面是我的Java代码:
ECNamedCurveParameterSpec parameterSpec =
ECNamedCurveTable.getParameterSpec("prime256v1");
KeyPairGenerator keyPairGenerator =
KeyPairGenerator.getInstance("ECDH", "BC");
keyPairGenerator.initialize(parameterSpec);
KeyPair serverKey = keyPairGenerator.generateKeyPair();
PrivateKey priv = serverKey.getPrivate();
PublicKey pub = serverKey.getPublic();`
System.out.println(Base64.toBase64String(pub.getEncoded()));
最佳答案
请参阅以下链接以获取 MartijnDwars 的回答。 https://github.com/web-push-libs/webpush-java/issues/30
you can use Utils.savePublicKey to convert your Java-generated PublicKey to a byte[]. This byte[] is then passed to the PushManager.subscribe method.
It may be more convenient to base64 encode the byte[] in Java and base64 decode the string in JavaScript. For example, after generating the keypair in Java:
KeyPair keyPair = generateKeyPair(); byte[] publicKey = Utils.savePublicKey((ECPublicKey) keyPair.getPublic()); String publicKeyBase64 = BaseEncoding.base64Url().encode(publicKey); System.out.println("PublicKey = " + publicKeyBase64); // PublicKey = BPf36QAqZNNvvnl9kkpTDerXUOt6Nm6P4x9GEvmFVFKgVyCVWy24KUTs6wLQtbV2Ug81utbNnx86_vZzXDyrl88=
Then in JavaScript:
function subscribe() { const publicKey = base64UrlToUint8Array('BPf36QAqZNNvvnl9kkpTDerXUOt6Nm6P4x9GEvmFVFKgVyCVWy24KUTs6wLQtbV2Ug81utbNnx86_vZzXDyrl88='); navigator.serviceWorker.ready.then(function (serviceWorkerRegistration) { serviceWorkerRegistration.pushManager.subscribe({ userVisibleOnly: true, applicationServerKey: publicKey }) .then(function (subscription) { return sendSubscriptionToServer(subscription); }) .catch(function (e) { if (Notification.permission === 'denied') { console.warn('Permission for Notifications was denied'); } else { console.error('Unable to subscribe to push.', e); } }); }); } function base64UrlToUint8Array(base64UrlData) { const padding = '='.repeat((4 - base64UrlData.length % 4) % 4); const base64 = (base64UrlData + padding) .replace(/\-/g, '+') .replace(/_/g, '/'); const rawData = atob(base64); const buffer = new Uint8Array(rawData.length); for (let i = 0; i < rawData.length; ++i) { buffer[i] = rawData.charCodeAt(i); } return buffer; }
关于java - 在 Java 中生成 VAPID key 并将其传递给 JavaScript PushManager,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44149608/