Quando o Chrome ofereceu suporte à API Web Push pela primeira vez, ele contava com a Firebase Cloud Messaging (FCM),anteriormente conhecido como Google Cloud Messaging (GCM), serviço push. Isso é necessário usando uma API reservada. Isso permitiu que o navegador Chrome para disponibilizar a API Web Push para desenvolvedores em um horário em que a especificação do protocolo de push da Web ainda estava sendo escrita e fornecida posteriormente autenticação (o remetente da mensagem é quem diz ser) por vez quando o protocolo de push da Web não tinha. Boa notícia: nenhuma das alternativas é verdadeira. mais
O FCM / GCM e o Chrome agora oferecem suporte ao Web Push Protocol padrão, enquanto o remetente a autenticação pode ser alcançada implementando VAPID, ou seja, seu app da Web não precisa mais de um "gcm_sender_id".
Neste artigo, vou descrever primeiro como converter seu servidor atual para usar o Web Push Protocol com o FCM. Em seguida, vou mostrar como implementar VAPID no código do cliente e do servidor.
O FCM oferece suporte ao protocolo de push da Web
Vamos começar com um pouco de contexto. Quando seu aplicativo da Web se registra
a assinatura de push recebe o URL de um serviço de push. Seu servidor usará
esse endpoint para enviar dados ao usuário pelo seu app da Web. No Chrome, você poderá
recebe um endpoint do FCM se você inscrever um usuário sem VAPID. Falaremos sobre VAPID
mais tarde). Antes de o FCM oferecer suporte ao protocolo push da Web, era preciso extrair o arquivo
ID de registro no final do URL e colocá-lo no cabeçalho antes de
fazer uma solicitação à API FCM. Por exemplo, um endpoint do FCM de
https://android.googleapis.com/gcm/send/ABCD1234
, teria um registro
ID: "ABCD1234".
Agora que o FCM oferece suporte ao protocolo Web push, é possível deixar o endpoint intacto e usar o URL como um endpoint do protocolo de push da Web. Isso alinha Firefox e, esperamos, todos os outros navegadores futuros.)
Antes de nos aprofundarmos no VAPID, precisamos verificar se nosso código do servidor está correto. gerencia o endpoint do FCM. Abaixo está um exemplo de como fazer uma solicitação para um push serviço em Node. Observe que estamos adicionando a chave de API à solicitação para o FCM e cabeçalhos de cache válidos. Para outros endpoints de serviços de push, isso não será necessário. Para o Chrome anterior para a versão 52, Opera Android e Samsung Browser, também é necessário incluir um "gcm_sender_id" no manifest.json do seu app da Web. A chave de API e ID do remetente são usados para verificar se o servidor que está fazendo as solicitações está têm permissão para enviar mensagens ao usuário de destino.
const headers = new Headers();
// 12-hour notification time to live.
headers.append('TTL', 12 * 60 * 60);
// Assuming no data is going to be sent
headers.append('Content-Length', 0);
// Assuming you're not using VAPID (read on), this
// proprietary header is needed
if(subscription.endpoint
.indexOf('https://android.googleapis.com/gcm/send/') === 0) {
headers.append('Authorization', 'GCM_API_KEY');
}
fetch(subscription.endpoint, {
method: 'POST',
headers: headers
})
.then(response => {
if (response.status !== 201) {
throw new Error('Unable to send push message');
}
});
Lembre-se de que esta é uma alteração na API do FCM / GCM, portanto você não precisa atualizar seu basta alterar o código do servidor para definir os cabeçalhos, conforme mostrado acima.
Introdução ao VAPID para identificação do servidor
VAPID é o novo nome curto
"Identificação voluntária do servidor de aplicativos". Isso
a nova especificação define essencialmente um handshake entre o servidor do aplicativo e o servidor
e permite que o serviço de push confirme qual site está enviando as mensagens.
Com o VAPID, é possível evitar as etapas específicas do FCM para enviar uma mensagem push. Você
não precisam mais de um projeto do Firebase, um gcm_sender_id
ou
Cabeçalho Authorization
.
O processo é bastante simples:
- O servidor do aplicativo cria um par de chaves pública/privada. A chave pública é dados ao seu app da Web.
- Quando o usuário optar por receber push, adicione a chave pública asubscribe() do objeto de opções da chamada.
- Quando o servidor do app enviar uma mensagem push, inclua um JSON Web Token assinado junto com a chave pública.
Vamos analisar essas etapas em detalhes.
Criar um par de chaves públicas/privadas
Eu sou péssima em criptografia, então aqui está a seção relevante das especificações sobre o formato das chaves públicas/privadas VAPID:
Os servidores de aplicativos DEVEM gerar e manter uma assinatura Par de chaves utilizável com assinatura digital de curva elíptica (ECDSA, na sigla em inglês) sobre a curva P-256.
Veja como fazer isso na biblioteca de nós de push da web:
function generateVAPIDKeys() {
var curve = crypto.createECDH('prime256v1');
curve.generateKeys();
return {
publicKey: curve.getPublicKey(),
privateKey: curve.getPrivateKey(),
};
}
Como assinar com a chave pública
Para inscrever um usuário do Chrome para push com a chave pública VAPID, você precisa transmitir
a chave pública como um Uint8Array usando o parâmetro applicationServerKey
da
o métodosubscribe().
const publicKey = new Uint8Array([0x4, 0x37, 0x77, 0xfe, …. ]);
serviceWorkerRegistration.pushManager.subscribe(
{
userVisibleOnly: true,
applicationServerKey: publicKey
}
);
Você vai saber se funcionou examinando o endpoint no
objeto de assinatura, se a origem for fcm.googleapis.com
, está funcionando.
https://fcm.googleapis.com/fcm/send/ABCD1234
Como enviar uma mensagem push
Para enviar uma mensagem usando VAPID, você precisa criar um protocolo push solicitação com dois cabeçalhos HTTP adicionais: um cabeçalho de autorização e um Cabeçalho "Crypto-Key".
Cabeçalho de autorização
O cabeçalho Authorization
é um JSON Web Token (JWT) assinado com "WebPush". na frente dele.
O JWT é uma maneira de compartilhar um objeto JSON com uma segunda parte de modo que o remetente pode assinar e o destinatário pode verificar a assinatura é do remetente esperado. A estrutura de um JWT tem três strings criptografadas. unidas por um único ponto entre eles.
<JWTHeader>.<Payload>.<Signature>
Cabeçalho JWT
O cabeçalho JWT contém o nome do algoritmo usado para assinatura e o tipo de com base no token correto anterior. Para VAPID, isso precisa ser:
{
"typ": "JWT",
"alg": "ES256"
}
Em seguida, ele é codificado em base64 e forma a primeira parte do JWT.
Payload
Payload é outro objeto JSON que contém o seguinte:
- Público-alvo ("aud")
- Esta é a origem do serviço de push (NÃO é a origem do seu site).
Em JavaScript, faça o seguinte para conseguir o público-alvo:
const audience = new URL(subscription.endpoint).origin
- Esta é a origem do serviço de push (NÃO é a origem do seu site).
Em JavaScript, faça o seguinte para conseguir o público-alvo:
- Horário de vencimento ("exp")
- Esse é o número de segundos até que a solicitação seja considerada como expirou. Isso PRECISA ser realizado dentro de 24 horas após a solicitação ser feita, em UTC.
- Assunto ("sub")
- O assunto precisa ser um URL ou um URL do
mailto:
. Isso fornece um ponto de contato, caso o serviço de push precise entrar em contato com o remetente da mensagem.
- O assunto precisa ser um URL ou um URL do
Um payload de exemplo pode ser semelhante ao seguinte:
{
"aud": "http://push-service.example.com",
"exp": Math.floor((Date.now() / 1000) + (12 * 60 * 60)),
"sub": "mailto: my-email@some-url.com"
}
Esse objeto JSON tem URL codificado em base64 e forma a segunda parte do JWT.
Assinatura
A assinatura é o resultado da junção do cabeçalho e do payload codificados com uma em seguida, criptografando o resultado usando a chave privada VAPID criada anteriormente. O resultado em si deve ser anexado ao cabeçalho com um ponto.
Não vou mostrar um exemplo de código para isso, porque há várias bibliotecas que usam o cabeçalho e o payload objetos JSON e gerar essa assinatura para você.
O JWT assinado é usado como o cabeçalho de autorização com "WebPush" anexado a e será semelhante a esta:
WebPush eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.eyJhdWQiOiJodHRwczovL2ZjbS5nb29nbGVhcGlzLmNvbSIsImV4cCI6MTQ2NjY2ODU5NCwic3ViIjoibWFpbHRvOnNpbXBsZS1wdXNoLWRlbW9AZ2F1bnRmYWNlLmNvLnVrIn0.Ec0VR8dtf5qb8Fb5Wk91br-evfho9sZT6jBRuQwxVMFyK5S8bhOjk8kuxvilLqTBmDXJM5l3uVrVOQirSsjq0A
Observe alguns detalhes sobre isso. Primeiro, o cabeçalho "Authorization" literalmente contém a palavra "WebPush" seguido de um espaço e do JWT. Além disso, observe os pontos separando o cabeçalho, o payload e a assinatura do JWT.
Cabeçalho Crypto-Key
Além do cabeçalho "Autorização", você precisa adicionar sua chave pública VAPID ao
Cabeçalho Crypto-Key
como uma string codificada de URL base64 com p256ecdsa=
no prefixo.
p256ecdsa=BDd3_hVL9fZi9Ybo2UUzA284WG5FZR30_95YeZJsiApwXKpNcF1rRPF3foIiBHXRdJI2Qhumhf6_LFTeZaNndIo
Quando enviar uma notificação com dados criptografados, você
já estão usando o cabeçalho Crypto-Key
. Portanto, para adicionar o servidor de aplicativos
basta adicionar um ponto e vírgula antes de adicionar o conteúdo acima, o que resulta
em:
dh=BGEw2wsHgLwzerjvnMTkbKrFRxdmwJ5S_k7zi7A1coR_sVjHmGrlvzYpAT1n4NPbioFlQkIrTNL8EH4V3ZZ4vJE;
p256ecdsa=BDd3_hVL9fZi9Ybo2UUzA284WG5FZR30_95YeZJsiApwXKpNcF1rRPF3foIiBHXRdJI2Qhumhf6_LFTeZaN
Verdade dessas mudanças
Com o VAPID, você não precisa mais se inscrever em uma conta com o GCM para usar o recurso de push in. Chrome e é possível usar o mesmo caminho de código para inscrever um usuário e enviar uma para um usuário no Chrome e no Firefox. Ambos estão seguindo os padrões.
Tenha em mente que, no Chrome 51 e em versões anteriores, o Opera for
No navegador Android e Samsung, você ainda precisa definir o gcm_sender_id
no manifesto do seu app da Web e você precisará adicionar o cabeçalho Authorization ao
endpoint do FCM que será retornado.
Com o VAPID, é possível se desviar desses requisitos próprios. Se você implementar
O VAPID funciona em todos os navegadores que oferecem suporte a push na Web. Como mais navegadores
oferecer suporte a VAPID, você pode decidir quando soltar o gcm_sender_id
do seu
manifesto do aplicativo.