iOS sending push with APNs Auth Key: suddenly "403 Forbidden: {"reason":"InvalidProviderToken"}" - apple-push-notifications

I'm sending my push notifications with an APNs Auth Key ("never expires") which worked well until suddenly I get
403 Forbidden: {"reason":"InvalidProviderToken"}
as a response when sending push notifications. What could be the reason for this when it worked once and suddenly it doesn't without having an expiration date? In the meantime it worked again for some pushes, but now I get the error again... Did anyone else experience this?
EDIT
Not sure but it seems as if this only happens on the Ubuntu server, not on my local (OS X) machine...

we have exactly the same problem when sending pushes to different team ids using the same connection. The steps to reproduce are:
Open a connection to APNS and use the same connection to:
Send a token based push to topic com.companyA.xxx of team id 1234: APNS accepts and delivers the push successfully.
Send a token based push to topic io.companyB.xxx of team id 5678: APNS responds HTTP 400 BadRequest The device token does not match the specified topic
Send again a token based push to topic io.companyB.xxx of team id 5678: APNS responds HTTP 403 Forbidden: the provider token is not valid or the token signature could not be verified.
After this it becomes impossible to send any push and the connection has to be closed and reopened.
The workaround we ended up doing is to open one connection per team id. The APNS documentation does not mention anything like that so I do consider this as a bug and I opened a bug report.

I've seen this in a couple of circumstances:
Resubmitting expired provider tokens seems to get the token blacklisted and results in subsequent InvalidProviderToken rejections rather than ExpiredProviderToken rejections. Check you logs for token expiry messages. Check your system clock to make sure that you're not generating tokens with skewed timestamps.
Submitting to invalid topics will invalidate all provider tokens on the connection (even previously valid ones). Only submit to topics that the key is bound to and only use one key per connection.

For me, there was an issue with bad configuration. I was using the wrong Team ID. Please make sure that all configuration is correct before you look into any other solutions.

The server does respond with an InvalidToken and/or an ExpiredToken error. Your authentication token shouldn't contain any '=', '+', '-', Double check if your token hasn't this any of those. Also the signature (3rd part of the token, should be Base64URL encoded, so without the previous mentioned characters).

for me the server time was invalid, fixing the server time solved the issue

I asked Apple to change my account from a personal account, to a business account. My push notification certificate still said everything was fine, but the notifications weren't working, and I was getting the response Invalid Token. Once I revoked the certificate and issued a new one (in apple connect), everything worked fine.
I wasted so much time trying to figure out why the push notifications weren't working. Hopefully this will save someone else some time!

I had been using the Name of the key instead of the Key ID. Verifying on https://developer.apple.com/account/resources/authkeys/review/ showed the correct value.

My case is with the json pretty print format. Unlike musickit which can accept jwt pretty print format, the APNs only accept the raw format.
In details:
My message was:
{
"alg": "ES256",
"kid": "SOMEKEYID"
}
{
"iss": "SOMETEAM",
"iat": 1581110460
}
I verified the result jwt via jwt.io, however the APNs keeps telling me InvalidProviderToken. I have tried everything above. No use.
Finally I changed the message to:
{"alg":"ES256","kid":"SOMEKEYID"}
{"iss":"SOMETEAM","iat":1581128155}
then it pass with no error.
Turns out APNs do not accept json pretty format!

Apple's APN documentation says:
APNs supports only provider authentication tokens that are signed with
the ES256 algorithm. Unsecured JWTs [JSON Web Tokens], or JWTs signed
with other algorithms, are rejected, and your provider server receives
the InvalidProviderToken (403) response.
So, it appears that the problem is not with your auth kiey; it's actually an issue with the web token that was generated from your key.

Related

Pubnub Auth Key and Auth Key Safety (Grant Token)

I have stuck in here and couldn't find a solid solution.
I use PHP in server-side and Vanilla JS in the client side.
In server-side, I'm generating a auth token (https://www.pubnub.com/docs/general/basics/manage-access) for current logged in user's channel to make him able to read his channel messsages by the following code:
I'm also generating a new one when the key timeout so all OK with the generation.
But my problem is starts here:
I'm passing the key into the client like this:
And user is getting access to the channel. But the thing is, I'm passing this auth key to the client-side. Which is someone that get this user's auth token; can setup their own client and can read messages that sent to this user.
How can I deal with that?
And another one:
I'm publishing to a channel in PHP like this. But I'm able do to that without setting auth token. I'm sure auth token system is working because when I pass wrong auth key to the client it's giving 403 forbidden. But however, I'm able to publish to channel without auth key in here. Is this because it's server-side?
Thanks!
Googled everything...
someone that get this user's auth token; can setup their own client and can read messages that sent to this user
This authorization strategy is the same as JWT. How will someone get this auth token? If you are using a secure connection to your server (TSL, aka https), and your PHP server is secured, then that is all you can do. This is the internet :)
Now how secure is the end user's machine? Are they susceptible to phishing or other schemes that might allow a hacker to gain access to their machine? Humans are the easiest thing to hack and you can't really do anything to secure them ;)
So as far as PubNub is concerned with security, you are doing exactly what very large companies have been doing for over 10 years with PubNub. The question is how secure is your server that a hacker can't get access to your code and data and get your PubNub secret key. In my 9+ years at PubNub, I've never known this to happen.
granting permissions on your channel
You are granting too many permissions but it doesn't have any negative side effects.
read - subscribe (receive messages), fetch (messages from history), and some presence stuff (get/set state, here now)
write - publish (send messages)
get and set - this is for PubNub Objects only which is different than pub/sub.
Again, no harm comes from granting permissions that have no effect on the resources you are granting to but it adds to the size of the auth token (just a little bit in this case).
able do to that without setting auth token
When you do setToken you are setting that on the pubnub object that you use to invoke PubNub operations. The PubNUb SDK automatically adds the auth token as a query parameter in the request. So it is being passed automatically for you.
Open your browser console, select the Network tab, and look at any PubNub request/url. You will see the query parameter names auth and the value is your auth token.
PubNub Secret Key give you all access
The secret key gives your server the ability to grant permissions (generate an auth token) AND it gives your server all access to all things in your PubNub key set. Don't let that secret key get compromised.

Apple Token based push Notification return 200 Ok, No notification Recieved

we are migrating from Cert based Notification to Token based notifications,
I have my Device token and I generate JWT token using .p8 file, KId, App Id and issue time. iam using Curl command to send the Message to api.push.apple.com/3/device/.
Iam getting
HTTP/2 200
apns-id: C372B9BE-5C83-3CBB-0DF3-5B5B6D671B65 from Server, however, iam not receiving any notifications on to my Mobile.
any one aware of this issue, Please advise.
Appreciate it

Network Error only occurs when user is on AT&T 5Ge network AND user is logged in

I have built a mobile app using React Native.
This app connects with a REST API I built using the Laravel framework.
This API is hosted on a VPS and served over HTTPS.
The mobile app works as intended where I expect it to, with the exception of the following use case:
A user has an iPhone 8+. This user’s carrier is AT&T. The 5Ge, to be specific.
This user can download the app and install it no problem.
When they open the app, the app connects to the API, and gets the data to display on the home screen.
The user can login, using their credentials, which are sent to the API, and the API returns an access token on a valid login.
Every subsequent request, is sent with an Authorization header: Bearer [token]
These requests specifically, never reach the server. All authenticated routes for the API are unreachable for this user.
Users on other networks, like Verizon and TMobile, do not have this issue.
The mobile app uses Axios library for sending HTTP requests.
A timeout of 25000 (maximum that can be sent on the iOS?) is passed as an option to the authenticated action. The action fails for this user.
The error is caught and then sent to a public route on the API, without an Authorization header in the request.
This request reaches the server and adds the error message from the request from the mobile app, to the error log on my server.
When I inspect the error that was thrown by the authenticated action failure, it reads “Network error” with a code of 0.
If the timeout is set lower, at 15000, the error thrown by the failed authenticated action is a timeout error, exceeded 15000.
I have contacted AT&T today, and they said we should contact Apple.
After they patched us through to Apple, Apple said issue sounds like it is a cell tower issue, and offered to run diagnostics on the phone.
My question is: Why are the requests that contain an Authorization header Bearer token not able to reach my server when the user is on the AT&T network. Is the bearer token making the request bulky and slowing down the request to where our towers aren’t able to send it?
Or does AT&T have some kind of middleware that would trash the request for some reason?
Could the Authorization header cause AT&T to handle the request differently and send it some other way and in this way could DNS errors cause the request to fail in this way.
Please help, I hope I have explained it well enough.
Edit: Laravel Passport generates access_token for the authenticated API that is 1000+ characters in length. It looks like I can reduce that by about half. I am going to try that next.
I'm finding this is resolved now.
I did two things. I reset my Laravel Passport keys with a specified --length of 1024.
This resulted in my access tokens being around 557 characters long instead of 1000+
I also made some DNS changes in my subdomain. A scan I did showed a nameserver parent mismatch error between the subdomain and parent domain. I made the changes and got those warnings to go away.
These are the things I did. My two app users who are with the AT&T network carrier tested the app tonight after I did these changes.
They logged in. Opened the timeclock. Clocked in. And that request made it to my server like it was supposed to, with the new shorter access token.
I don't know which one of those two things fixed this issue. But I would probably guess it was the DNS problems that I resolved. I still find it odd that the issue only occured on the AT&T network when with an Authorization token in the header of the request.

Cognito reset session from server-side

I am curious if I can reset user sessions that is generated from mobile-end or front-end in a server.
My friend is working on iOS development, but he is having difficult time to make reset session function in his end. As a workaround, what I am thinking is (event if it is very dangerous and insecure approach...) he will send a refresh token and generate new tokens. New tokens will be fed back to the mobile.
However, this doesn't work. The error I am facing is "Invalid Refresh Token". What I am guessing is since it is generated from mobile end, the tokens cannot be generated in other sources, in this case the server.
Is this approach blocked by AWS side? Thanks.
If you are using Amazon Cognito, the globalSignOut and adminUserGlobalSignOut to invalidate issued access and refresh tokens for a user.

403 Forbidden error when deleting YouTube video

I have been using the OAuth approach to upload,update and delete videos on YouTube. That all has been working fine until about February 12th where all of those processes stopped working. Now when I go to delete a YouTube video I get the following error:
"code": 403,
"message": "The video that you are trying to delete cannot be deleted. The request might not be properly authorized."
I know that the OAuth process is working because I can get the token and refresh the token if it has expired. I'm using the latest PHP library that Google have provided (installed using composer). And I can get information about a valid YouTube video by making the following call:
$videoId = "xxxxxxx"; //id of video on YouTube
$youtube->videos->listVideos("snippet", array('id' => $videoId));
But then the delete call gives that error above.
$youtube->videos->delete($videoId);
Since the listVideos works, that confirms that the client_id, secret key and token is correct. I also am setting the scopes to be the following
$client->setScopes(array('https://www.googleapis.com/auth/youtube',
'https://www.googleapis.com/auth/youtube.upload',
'https://www.googleapis.com/auth/youtubepartner'));
I also checked that the credentials and quotas set in the Google APIs are ok. I thought that maybe the quota had been reached but that doesn't appear to be the case. I did see an email from YouTube in early february saying that they have a new terms of service and a developer policies. I reviewed all that but nothing in there appears to point to the issue I am having?
Not sure what else to try?
Try to check my answer here in this SO question that focus on how to Refresh Token with the Google API.
Your error usually caused by:
When the token expires
The token’s scope (this is important)
If the token is invalid
If the token is invalid you can troubleshoot like this:
Remove the access token from your datastore or database.
Use the refresh token to acquire a new access token (if you are using a refresh token)
Try to make the API call again. If it works, you’re good! If not …
Check the access token against the tokenInfo API
If it’s still invalid, do a full reauth
Hope this helps!

Resources