web-push-php icon indicating copy to clipboard operation
web-push-php copied to clipboard

Microsoft Edge Always Returns 401 Not Authorised Invalid Token

Open andystables opened this issue 5 years ago • 16 comments

NOTE: Please test in a least two browsers (i.e. Chrome and Firefox). This helps with diagnosing problems quicker.

Please confirm the following:

  • [ x] I have read the README entirely
  • [x ] I have verified in the issues that my problem hasn't already been resolved

Setup

Please provide the following details, the more info you can provide the better.

  • Operating System: Windows
  • PHP Version: 7.3
  • web-push-php Version: 5.2

Please check that you have installed and enabled these PHP extensions :

  • [x ] gmp
  • [x ] mbstring
  • [x ] curl
  • [x ] openssl

Please select any browsers that you are experiencing problems with:

  • [ ] Chrome
  • [ ] Firefox
  • [ ] Firefox for Mobile
  • [ ] Opera for Android
  • [ ] Samsung Internet Browser
  • [x ] Other

Please specify the versions (i.e. Chrome Beta, Firefox Beta etc). Microsoft Edge 44.17763.1.0

Problem

Please explain what behaviour you are seeing.

When pushing to subscription endpoint in Edge, a 401 error is always returned with the WWW-Authenticate header containing 'bearer error="invalid_request",error_description="Invalid token".

I think this may be because Microsoft Push Notification Service requires a (Bearer) Access Token to be passed in the Authorisation header as explained in https://docs.microsoft.com/en-us/previous-versions/windows/apps/hh868206(v%3dwin.10).

Does this library have a facility to pass the bearer token to Microsoft Endpoints? If so, please could the README be updated to provide example of how to make a push to Microsoft Push Service.

If not is it possible to extend the library to allow custom HTTP headers to be inserted into the post to the notification endpoints?

Expected

Please explain what you expected to happen

Push notification to be sent to device.

Features Used

  • [x ] VAPID Support
  • [x ] GCM API Key
  • [x ] Sending with Payload

Example / Reproduce Case

Please provide a code sample that reproduces the issue. If there is a repository that reproduces the issue please put the link here.

Other

Please put any remaining notes here.

andystables avatar May 28 '19 19:05 andystables

same issue > Chrome, Firefox and Opera works but not Microsoft Edge 44.18362.449.0 / Microsoft EdgeHTML 18.18362

I got the following response:

[x] Message failed to sent for subscription https://am3p.notify.windows.com/w/?token=........
Client error: `POST https://am3p.notify.windows.com/w/?token=........`
resulted in a `401 Unauthorized` response

How to fix the issue

appzer avatar Jan 10 '20 15:01 appzer

Same issue .... Works fine on Mozilla, Chrome. On Microsoft always get 401 UnAuthorised response.

gauravag09 avatar Apr 04 '20 02:04 gauravag09

Hello? anything?

llioorkd avatar Oct 01 '20 11:10 llioorkd

My Microsoft Edge on Windows 10 2004 works fine, but not on 1607 (LTSB). Receive 401 all the time. At the same time Microsoft's test page ( https://webpushdemo.azurewebsites.net/ ) works fine on both versions of Windows.

Korzhukov avatar Nov 12 '20 11:11 Korzhukov

Also a 401 all the time, the webpushdemo works. Chrome and firefox also work, it's just Edge that doesn't.

Edge version: 44.19041.1.0 EdgeHTML version: 18.19041 Windows 10 version: 19041.264

noesnaterse avatar Feb 18 '21 15:02 noesnaterse

see bug #278 I can confirm changing anything on the token of the endpoint (url encoding) will let the request fail. E.g. in our case "%2b" was decoded to "+" but not encoded again. "%2f" was translated to "%2F"; so make sure to base64 encode the endpoint, write it to the database as it is and use it.

mokraemer avatar Feb 24 '21 13:02 mokraemer

i can confirm, replacing "+" to "%2b" works

appzer avatar Feb 24 '21 18:02 appzer

God bless you mokraemer. Replacing '+' with '%2b' works!!!

andystables avatar Feb 24 '21 19:02 andystables

Hi together,

I still don't understand: If I allow the browser notifications in edge, I receive a subscription endpoint in following format direct from the browser into my backend and store it to database:

https://wns2-par02p.notify.windows.com/w/?token=BQYAAACnq6s4RQFlGHbZdME3cx03PENrEhpbmIqJUsfd4II9rHsvqUGR86doPTU1KiZfds%2fQu8jx9cijQjI6e8tyZqtR%2bcbcZVnHu%2fZWhMU1c35XCeBGTXZYUvUdwQ1O8a0kBIyPolLayZccLZIVZV7b6hs5zgHPuU0pYKpw4vJy2QoTG0WmjD8bIsk6oc5M46cATwiCz

The token looks already url-encoded.

But if I reuse it exactly as it is, I run into 401 error bearer error invalid token. So what can I do? Can anybody help?

trailsnail avatar Mar 25 '22 08:03 trailsnail

Make sure to base64 encode the string and decode it just before sending! Some libs make an url_decode and reencode the token, so %2f becomes %2F which is correct, but MS refuses if the token does not match byte by byte. You should check your request with the debugging console.

mokraemer avatar Mar 25 '22 09:03 mokraemer

Make sure to base64 encode the string

While storing the subscription or right before sending a notification?

I ask, because no matter how I do it: the request contains after decoding already the variant I stored into database with subscription grafik

The encode and decode results in no success ...

grafik

trailsnail avatar Mar 25 '22 10:03 trailsnail

Damn, one problem solved: the endpoint length is more than 255 chars...

Ok... now the encoding problem ... I am still investigating 😆

Finally the message was created ... token length in database was the problem.

grafik

Now I have to find out, why message does not appear in Edge => Windows 11 Notfiy Settings 🤣 Now all works as expected - no encoding, no decoding, only the database field was too short

trailsnail avatar Mar 25 '22 10:03 trailsnail

Hello @mokraemer, I am having the same issue on Edge.

I have this endpoint: https://wns2-bl2p.notify.windows.com/w/?token=BQYAAAAAgYrxLzjPS7Xx2t9XoqmGVxPKRhhhwinm6Fe8Bkg%2fcpadDTvEh8X9HC3FxsIW2KLCllCY8DlvFLuv45%2b4MZyRZ9IBbmE%2fslIuv3oP%2fELOQ%2f6j7rexCTjXLfsGOsjZG8rpyngxm4ZUuFwF%2bhxBbm9P1%2fj5vTxp%2b8H2dI1StYQLODdqI%2bwVIb86hPO

and after decoding it, became like this: https://wns2-bl2p.notify.windows.com/w/?token=BQYAAAAAgYrxLzjPS7Xx2t9XoqmGVxPKRhhhwinm6Fe8Bkg/cpadDTvEh8X9HC3FxsIW2KLCllCY8DlvFLuv45+4MZyRZ9IBbmE/slIuv3oP/ELOQ/6j7rexCTjXLfsGOsjZG8rpyngxm4ZUuFwF+hxBbm9P1/j5vTxp+8H2dI1StYQLODdqI+wVIb86hPO

But I'm still getting Received unexpected response code: 401.

Am I doing something wrong here?

louieje-g avatar Sep 20 '22 15:09 louieje-g

But I'm still getting Received unexpected response code: 401.

Am I doing something wrong here?

Shortly before end of work, I quickly looked at our code: I also use my endpoint urls plain urlencoded as I originally received them, so with "%" and so. .../?token=BQYAAACHbfSJe%2fmCFNlN3OWqm%2bwt4RCsqm7IL3hA8DWTyXhKB55ceXAak4QHQdzxeW5Br0e7LnkVEpZy%2fkDSGn%2fM7L6uA8V%2fn7x3%2b4pcfDjXsFZL8zAH80vTiJHPqKRsjpzG5sra5dVLMBwLOnjPIzQ%2f2%2fxqKpMdx2efVSkhoVzp0Vu%2flpz4qebU691%2flc7e5gcCYucoOn36Juaa6yk%2flpaltWIO5PiKsJh5JbETOwB%2bR0D0jnVgHEYzDqCHWOTJX44hcqTUXGVy8Q%2bZQQrukJKLZrBA7q...

And this works fine with this code and without any encoding/decoding on our side

/**
     * @param list<Subscription> $subscriptions
     */
    private function sendNotifications(array $subscriptions): void
    {
        $auth = [
            'VAPID' => [
                'subject' => 'YOUR SUBJECT',
                'publicKey' => WEBPUSH_VAPID_PUBLIC_KEY,
                'privateKey' => WEBPUSH_VAPID_PRIVATE_KEY,
            ],
        ];

        $webPush = new \Minishlink\WebPush\WebPush($auth);

        foreach ($this->createNotfications($subscriptions) as $notification) {
            $webPush->queueNotification(
                $notification['subscription'],
                $notification['payload'],
            );
        }

        foreach ($webPush->flush() as $report) {
            $endpoint = $report->getRequest()->getUri()->__toString();

            if (!$report->isSuccess()) {
                (new SubscriptionRepository())->deleteSubscription($endpoint);
            }
        }
    }

    /**
     * @param list<Subscription> $storedSubscriptions
     *
     * @return list<array{subscription: \Minishlink\WebPush\Subscription, payload: string}>
     */
    private function createNotfications(array $storedSubscriptions): array
    {
        $notifications = [];
        foreach ($storedSubscriptions as $storedSubscription) {
            $notifications[] = [
                'subscription' => \Minishlink\WebPush\Subscription::create([
                    'endpoint' => $storedSubscription->endpoint,
                    'publicKey' => $storedSubscription->publicKey,
                    'authToken' => $storedSubscription->authToken,
                    'contentEncoding' => $storedSubscription->contentEncoding,
                ]),
                'payload' => $this->getPayload(),
            ];
        }

        return $notifications;
    }

At first I thought I was having encoding problems as well. But the problem was that I didn't have the complete endpoint stored in the DB, the field was too short. Because of the wrong endpoint I also got 401

trailsnail avatar Sep 20 '22 15:09 trailsnail

@trailsnail You're actually right, it was the column length on the DB that was too short 😅 . Sorry I didn't noticed your previous comment regarding that. Thank you so much, you saved my life 😁.

louieje-g avatar Sep 20 '22 16:09 louieje-g

I had the exact same issue and realized thanks to this discussion that my DB field was too short as well 😅

ndebarnot avatar Nov 09 '23 10:11 ndebarnot