Closed tintin10q closed 1 year ago
no, it's right, and working as intended.
Vapid 'aud' is the aud
ience of the VAPID assertion, it's supposed to be the host string, so in your case it would be https://fcm.googleapis.com
. (There's an example down in section 2.4 of the RFC.
You're confusing it with the FCM endpoint, which you definitely should not share outside of your application. (Other sites would still need your credentials to send information, but no need to make things easier for them to do attacks.)
I added that filter partly because a LOT of folks tend to get that confused and wind up accidentally leaking info that they shouldn't, so Good News! You're not the only one that finds all this weirdly confusing.
Hope that helps.
Thanks that does help. It is quite confusing indeed.
I wonder though when would you ever send the jwt I was trying to make to some other place then the fcm endpoint?
Ah, so the way that all this works is that you use the VAPID header as the "Authorization:" header value when you POST to the FCM endpoint.
If you like, you might want to look at the pywebpush library that does a lot of this for you. Just one note of caution, while you can absolutely call pywebpush.webpush(...)
and things will work, if you're doing anything beyond just sending a few test messages around, it's probably best to look at what's going on in that function and call WebPusher.send(...)
.
One of the big reasons is that webpush
does a lot of extra things you don't always need to do, like regenerate your VAPID header, which you don't have to do very often. (Maybe once a week or month or so is plenty.) Also, remember that the VAPID public key is what you use to "lock" subscriptions to you, so when you change the VAPID key for whatever reason, all your endpoints become instantly invalid. Make sure that your clients recreate the subscription when you do that.
Thank you. I was going to use this library but then when I thought that the regex thing was a mistake I actually ended up using this library: https://pypi.org/project/webpush/. I did also look at the one you linked but it says it was work in process so I went for that one. Now I see that pywebpush actually uses this library so that is nice. An annoying thing about the library I am using now is that they want the keys as file paths so they can open the files themselves.
What I also find quite confusing is that I feel like there were/are multiple versions of this push notification system around but it is not always clear which one the code expects you to use. For instance in the rfc it says nothing about gcm encryption. Never mind. I just saw that the rfc that the article that the library I ended up using links to is actually an old version of the spec. That is exactly what I mean. Also the Crypto-Key header. I could not really find that in the rfc either. But it seems to do something important.
I thought that you actually needed to sign a new jwt for every push message. Thank you for pointing out that this is not the case. I could do some caching based on the endpoint hosts.
Thanks again, this picture is very appropriate I feel.
I wrote this (and pywebpush) pretty much because nothing existed at the time. And I fully expected someone to come up with something better. That... did not happen.
If you knew how many key python systems used it, you would also be horrified.
To be clear, FCM/GCM and APNS are their own push systems. They also provide support for RFC WebPush, but add in some interesting complications. (FCM requires VAPID even though the very first word in that Acronym is "Voluntary", but 🤷🏻♂️ )
Getting into Push, the current specification uses RFC VAPID as the Authorization header and encodes the cryptographic elements into the payload using aes128gcm
encoding (The GCM here is not Google Cloud Messaging but Galois/Counter Mode, in case you want to impress dates or something.) See https://www.rfc-editor.org/rfc/rfc8291.html for the details. Unless you have better things to do, which you probably do.
The Crypto-Key
header is from an older version of WebPush, and should not be used.
Honestly, if you want to send web push, it's probably best to just use a library that does all the leg work for you. Then, at least, you can get on and worry about all the other fun issues, like "Wait, why isn't my serviceworker getting called?" and "Should I implement support for pushsubscriptionchangeevent
?" (Yes, yes you should. It's important.)
This also is pretty good: https://github.com/delvinru/webpush-py at least simple.
In the python code in the
_base_sign
function you have:But this seems wrong. My chrome endpoint looks like this:
https://fcm.googleapis.com/fcm/send/some-letters:abun-more-letters
So it seems that this regex is wrong and that you need to change the
[^/:]+
part into maybe like.+