pywebpush: 403 MismatchSenderId

Any idea how to solve or debug this error? I’m using the latest version from master.

https://stackoverflow.com/questions/53875035/how-to-fix-403-mismatchsenderid-when-sending-web-push-notifications

I get the following traceback:

pytest test_push.py
====================================================== test session starts =======================================================
platform darwin -- Python 3.6.2, pytest-3.9.1, py-1.7.0, pluggy-0.8.0
rootdir: /Users/kayibal/Downloads, inifile:
plugins: django-3.4.3
collected 1 item

test_push.py F                                                                                                             [100%]

============================================================ FAILURES ============================================================
___________________________________________________________ test_push ____________________________________________________________

subs = {'endpoint': 'https://fcm.googleapis.com/fcm/send/cvNVGGLtZVo:APA91bFqfRXSHhqdzv6MXFKu7SFUvqyPSRlSNxER2B9cIj5OQZAC1THz...w1dNBzuNYFG7FMA', 'p256dh': 'BDz4O5Lb96W133iNj7uEmN0nnZuCDQKg8DTqa4P50stLUJ0vXBhwLker4EyMtf_U2Hr-UFf084QCxwZSR_3F70A'}}
vapid_data = {'privateKey': 'Ew2kli-56Ps6FEspgshs9MnFhhuX2mlMdXqhZqisN5w', 'publicKey': 'BEtyWjkXAXTOTN-5X018konhbR5KpAaQbM4jcWptLDzO2Ia-tm93NCY72TMh5kYAjYDThYY40FGh2BFHJeSX-04', 'subject': 'mailto:tech@rect.ag'}

    def test_push(subs, vapid_data):
        webpush(subs,
                'Your Push Payload Text',
                vapid_private_key=vapid_data['privateKey'],
                vapid_claims={"sub": "mailto:tech@rect.ag"},
>               ttl=2419200,
                )

test_push.py:27:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

subscription_info = {'endpoint': 'https://fcm.googleapis.com/fcm/send/cvNVGGLtZVo:APA91bFqfRXSHhqdzv6MXFKu7SFUvqyPSRlSNxER2B9cIj5OQZAC1THz...w1dNBzuNYFG7FMA', 'p256dh': 'BDz4O5Lb96W133iNj7uEmN0nnZuCDQKg8DTqa4P50stLUJ0vXBhwLker4EyMtf_U2Hr-UFf084QCxwZSR_3F70A'}}
data = 'Your Push Payload Text', vapid_private_key = 'Ew2kli-56Ps6FEspgshs9MnFhhuX2mlMdXqhZqisN5w'
vapid_claims = {'aud': 'https://fcm.googleapis.com', 'exp': 1548326836, 'sub': 'mailto:tech@rect.ag'}
content_encoding = 'aes128gcm', curl = False, timeout = None, ttl = 2419200

    def webpush(subscription_info,
                data=None,
                vapid_private_key=None,
                vapid_claims=None,
                content_encoding="aes128gcm",
                curl=False,
                timeout=None,
                ttl=0):
        """
            One call solution to endcode and send `data` to the endpoint
            contained in `subscription_info` using optional VAPID auth headers.

            in example:

            .. code-block:: python

            from pywebpush import python

            webpush(
                subscription_info={
                    "endpoint": "https://push.example.com/v1/abcd",
                    "keys": {"p256dh": "0123abcd...",
                             "auth": "001122..."}
                     },
                data="Mary had a little lamb, with a nice mint jelly",
                vapid_private_key="path/to/key.pem",
                vapid_claims={"sub": "YourNameHere@example.com"}
                )

            No additional method call is required. Any non-success will throw a
            `WebPushException`.

        :param subscription_info: Provided by the client call
        :type subscription_info: dict
        :param data: Serialized data to send
        :type data: str
        :param vapid_private_key: Vapid instance or path to vapid private key PEM \
                                  or encoded str
        :type vapid_private_key: Union[Vapid, str]
        :param vapid_claims: Dictionary of claims ('sub' required)
        :type vapid_claims: dict
        :param content_encoding: Optional content type string
        :type content_encoding: str
        :param curl: Return as "curl" string instead of sending
        :type curl: bool
        :param timeout: POST requests timeout
        :type timeout: float or tuple
        :param ttl: Time To Live
        :type ttl: int
        :return requests.Response or string

        """
        vapid_headers = None
        if vapid_claims:
            if not vapid_claims.get('aud'):
                url = urlparse(subscription_info.get('endpoint'))
                aud = "{}://{}".format(url.scheme, url.netloc)
                vapid_claims['aud'] = aud
            if not vapid_claims.get('exp'):
                # encryption lives for 12 hours
                vapid_claims['exp'] = int(time.time()) + (12 * 60 * 60)
            if not vapid_private_key:
                raise WebPushException("VAPID dict missing 'private_key'")
            if isinstance(vapid_private_key, Vapid):
                vv = vapid_private_key
            elif os.path.isfile(vapid_private_key):
                # Presume that key from file is handled correctly by
                # py_vapid.
                vv = Vapid.from_file(
                    private_key_file=vapid_private_key)  # pragma no cover
            else:
                vv = Vapid.from_string(private_key=vapid_private_key)
            vapid_headers = vv.sign(vapid_claims)
        response = WebPusher(subscription_info).send(
            data,
            vapid_headers,
            ttl=ttl,
            content_encoding=content_encoding,
            curl=curl,
            timeout=timeout,
        )
        if not curl and response.status_code > 202:
            raise WebPushException("Push failed: {} {}".format(
                response.status_code, response.reason),
>               response=response)
E           pywebpush.WebPushException: WebPushException: Push failed: 403 MismatchSenderId

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 15 (6 by maintainers)

Commits related to this issue

Most upvoted comments

HA! I found it ! the problem is in the combination of calling webpush and HA. Because webpush modifies his argument vapid_claims and add ‘exp’ if missing (it is set to +12h) But when you call webpush(vapid_claims=self._vapid_claims) then the modification saves also into the class object. So next time of call webpush, the ‘exp’ is already in vapid_claims and is not updated.

I propose to make local copy of vapid_claims in webpush and then modify it. What you think @jrconlin ?