Does the Device Library Identifier change with the Push Token? - applepay

According to this answer, push tokens are regularly rotated to help with privacy, and that my web service API implementation will see this as a new registration.
Does this mean that the web service API registration endpoint must detect the same device library identifier with a different pushToken as a different device? Or, does the device library identifier also change with the pushToken?

Both the device library identifier and the push token are regularly randomised. When a push token is rotated, you will receive a registration request with a new device library identifier and push token. You will not receive an I register request for the old identifier and token.
When making a push request for a token that has been rotated, you will receive a response from APNS letting you know that the token is no longer valid.
Therefore, when a device has rotated it’s token and you haven’t sent a push request, your database should show it registered with 2 identifiers.

Related

Force APNS device token to renew

Is there anyway to force the APNS device token to renew? Our users are occasionally getting duplicate push notifications. Is it possible that the device token renews and we momentarily have two tokens registered for the same device? It's my understanding that when the token renews the old one is immediately invalidated and APNS will return a 410 error if we try to send notifications to the old token is that correct?
It would be good if we could test the renewal process and see if there are any bugs with that.

After fetching the access token to perform API requests on user's behalf, whats the "proper" way to keep the user session and token connected?

I'm currently developing an identity 4 server, an API protected by scopes defined on the identity server and the mobile app server which will consume information from the API.
By now I already got a good grasp of how to use the authorization and access tokens and how to perform the correct flows, however I got into a dilemma when I started looking at the user session between the mobile app and server. After receiving the access and identity token, which basically serves as confirmation of user login/authorization, which would be the "proper" way to store it and keep the session alive with the app?
Initially I thought of using using cookies, but was told it doesn't work well with mobile apps (I barely know anything about android/ios), to which I followed by considering the creation of JWT on the server, which seemed wrong considering the existence of the identity server that was already producing tokens. And with this, how would I related the session to the access token to perform the API requests?
TLDR:
After fetching access and id token for the client, what "proper"
methods are there to keep sessions alive between client and mobile app?
How to relate the session to the access token to use when API requests are necessary?
Thanks !
For a modern native mobile app I'd suggest using the authorization_code flow (via the default browser on the device) with PKCE and storing a refresh token in the secure enclave of the device. This can then be protected by built in PIN or biometric features.
With that (carefully protected) refresh token you can maintain a long lived session without the need to do front channel (i.e. web browser) interactions with the OIDC service.

How to OAuth using WeChat Login for Parse Server

We would like to enable WeChat Login on our iOS client that is connected to a Parse Server backend on Heroku. From reading through the PFFacebookAuthenticationProvider, it seems that we need to write a custom authentication provider for WeChat.
WeChat Login is based on OAuth 2.0. It works as followed:
1. From our app, an authorization request is sent to the WeChat app installed on the same phone. WeChat app is called to the foreground.
2. After user approved the authorization request, a code (NOT the access token) is sent to our app.
3. With the code and our app id and app secret, our server can then call WeChat API and get the appropriate user id and access token from WeChat. This step has to happen on our server, as we cannot include the app secret within our client app.
On the WeChat documentation, it is strongly recommended that we keep the access token strictly in the control of server (anyone with the access token can make requests to WeChat API and it will be counted towards the usage limit for our API calls).
If we are to follow this practice, we cannot save the access token in the authData field of the user. Would it be acceptable to save only the code and id from WeChat into the authData and save the access token to another class that only the master key has access to? This obviously requires us to write a custom AuthAdapter for the Parse Server.
Or is there a better way to implement this custom auth? The custom auth documentation for Parse Server is pretty thin and I plan to improve it after I can get it working for myself.
You can definitely update the auth adapter to exchange the code for an access token server side. The logic would be similar to other adapters, failing to login/signup if the server is unable to process the code to access token exchange.
Here
https://github.com/parse-community/parse-server/blob/master/src/Adapters/Auth/wechat.js#L7
If the authData object has that code, you can add additional logic to exchange it.

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

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.

MDM Device token issue

I have setup simple demo for MDM server. I can successfully recover initial plist with messagetype, pushmagic token, APNs token(32byte as base46) and unlocktoken. My issue is when I tried to decode APNs token using base64_decode php function, it returns with junk/garbage character. Can any help if I need to use anyother php function to decode APNs token?
Thanks,
Viral.
The token is just what it is: a token. What you're getting with base64_decode is just a byte-array, you cannot see any meaningful data in it or print it as a string. Just store it in binary form in your database. You need this token later on to identify the target device when you send a pending command notification to the APNS. It is the actually the same as a push-token for an app.
The content of the notification for the device is described in 1, and the APNS protocol in [2].
References
Apple Inc, Mobile Device Management Protocol Reference
Apple Push Notification Service
Just to add onto this. If you're using another library to abstract sending notifications, sometimes they expect the token to be 64 characters. With PHP, you can do this with $token = bin2hex(base64_decode($deviceToken));
However if the token is stored in your database as binary format, then the base64_decode can be omitted. The following is what is required when dealing with PHP PDO w/ Postgres:
bin2hex(stream_get_contents($deviceToken))

Resources