Skip to content

Support Apple's APNS Token Authentication #50

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
natanrolnik opened this issue Jan 4, 2017 · 10 comments · Fixed by #174
Closed

Support Apple's APNS Token Authentication #50

natanrolnik opened this issue Jan 4, 2017 · 10 comments · Fixed by #174

Comments

@natanrolnik
Copy link
Contributor

(Issue originally opened by @EricNetsch in parse-community/parse-server#3315)

I would like to start using Apple's new push notification authentication protocol instead of using traditional certs. Is this possible with parse-server yet? This would be a fantastic addition to the platform to simplify push certificate management.

Provider Authentication Tokens

To securely connect to APNs, you can use provider authentication tokens or provider certificates. This section describes connections using tokens.

The provider API supports the JSON Web Token (JWT) specification, letting you pass statements and metadata, called claims, to APNs, along with each push notification. For details, refer to the specification at https://tools.ietf.org/html/rfc7519. For additional information about JWT, along with a list of available libraries for generating signed JWTs, see https://jwt.io

A provider authentication token is a JSON object that you construct, whose header must include:

The encryption algorithm (alg) you use to encrypt the token
A 10-character key identifier (kid) key, obtained from your developer account
The claims payload of the token must include:

The issuer (iss) registered claim key, whose value is your 10-character Team ID, obtained from your developer account
The issued at (iat) registered claim key, whose value indicates the time at which the token was generated, in terms of the number of seconds since Epoch, in UTC
After you create the token, you must sign it with a private key. You must then encrypt the token using the Elliptic Curve Digital Signature Algorithm (ECDSA) with the P-256 curve and the SHA-256 hash algorithm. Specify the value ES256 in the algorithm header key (alg). For information on how to configure your token, search Xcode help for the phrase “Configure push notifications.”

A decoded JWT provider authentication token for APNs has the following format:

{
"alg": "ES256",
"kid": "ABC123DEFG"
}
{
"iss": "DEF123GHIJ",
"iat": 1437179036
}
NOTE

APNs supports only provider authentication tokens that are signed with the ES256 algorithm. Unsecured JWTs, or JWTs signed with other algorithms, are rejected, and your provider server receives the InvalidProviderToken (403) response.

To ensure security, APNs requires new tokens to be generated periodically. A new token has an updated issued at claim key, whose value indicates the time the token was generated. If the timestamp for token issue is not within the last hour, APNs rejects subsequent push messages, returning an ExpiredProviderToken (403) error.

https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html

Please advise on any existing solutions/ implementations.

@natanrolnik
Copy link
Contributor Author

@EricNetsch I was planning to do this but I wasn't sure about the implementation. The dependency used here, APN, already supports using APNS authentication tokens. But it's a major update on their package, that has some breaking changes to the one currently used here.

@EricNetsch
Copy link

@natanrolnik Ok, got it. It definitely adds some complexity to the token management and would require a cache per "defaultTopic" or bundle Id. This feature is critical for one of our projects which supports multiple iOS applications on one parse-server (multiple bundle ID's). Please keep me updated and let me know how I can help

@natanrolnik
Copy link
Contributor Author

natanrolnik commented Jan 4, 2017

@EricNetsch if I remember correctly, you already can send push to multiple applications with different bundle ids in the current versions. Take a look here, and check how you can pass an array of configurations.

@funkenstrahlen
Copy link
Contributor

I would also love to see this supported.

@EricNetsch
Copy link

@natanrolnik that's not good solution. We need to be able to support dynamic bundle ID's without re-deploying the server code every time we have a new app. Using the tokenized method is the right solution

@natanrolnik
Copy link
Contributor Author

@EricNetsch if I remember correctly, the module apn also requires the bundle id, otherwise it's not able to package the JWT. I might be wrong, but if that's the case, it would need re-deploying anyway.

@EricNetsch
Copy link

EricNetsch commented Jan 19, 2017

Yes, it does require a bundle ID to create a token. The idea is that you could pass it the bundle ID (dynamically) to create the token. All bundle ID's will work if they share the same Team Identifier. This would allow us to create tokens for new apps without having to re-deploy/update the server code. The bundle ID could be passed as a parameter when creating a token.

@natanrolnik
Copy link
Contributor Author

natanrolnik commented Feb 8, 2017

There is a PR open that enables support for APNS Auth Token. You can look at it here: #52

However, @EricNetsch, the current implementation on that PR does require a deploy in order to add/remove bundle IDs.

@flovilmart
Copy link
Contributor

@natanrolnik with the release of v2.0.0 that features APNS v2 is that issue still relevant?

@natanrolnik
Copy link
Contributor Author

🙏🏻🎉

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants