Skip to content
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

use token and algo from jwt header #6416

Merged
merged 13 commits into from
Mar 11, 2020

Conversation

andrewking0207
Copy link
Contributor

@andrewking0207 andrewking0207 commented Feb 17, 2020

Fixes: #6408

The appleid auth token endpoint https://appleid.apple.com/auth/keys returns three different keys. The current apple auth adapter implementation always selects the first key to verify the token. This works often but if the client did not encode using the first key then the verification will fail. This fix checks the header of the token to get the key ID used for the encoding and then selects the correct public key with which to perform verification of the token.

Also selects the encryption algorithm from the header in case Apple changes what they use in the future.

@andrewking0207
Copy link
Contributor Author

I'm not sure what to do about those failing tests. They don't seem related, I'm guessing they pass locally because I don't have an actual replicaset and redis cache?

@codecov
Copy link

codecov bot commented Feb 17, 2020

Codecov Report

Merging #6416 into master will decrease coverage by 0.67%.
The diff coverage is 100.00%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #6416      +/-   ##
==========================================
- Coverage   93.96%   93.29%   -0.68%     
==========================================
  Files         169      169              
  Lines       11801    11989     +188     
==========================================
+ Hits        11089    11185      +96     
- Misses        712      804      +92     
Impacted Files Coverage Δ
src/Adapters/Auth/apple.js 100.00% <100.00%> (+12.90%) ⬆️
...dapters/Storage/Postgres/PostgresStorageAdapter.js 90.02% <0.00%> (-6.70%) ⬇️
src/RestWrite.js 93.64% <0.00%> (-0.17%) ⬇️
src/GraphQL/ParseGraphQLSchema.js 97.70% <0.00%> (+0.44%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 209d6f7...b3d353a. Read the comment docs.

Copy link
Member

@dplewis dplewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR. I have a few suggestions.

At some point we should move from node-rsa to jwks-rsa. As mentioned in the apple documentation, to get the public keys, we need to deal properly with json web keys (jwks) to get the signin keys.

https://developer.apple.com/documentation/signinwithapplerestapi/fetch_apple_s_public_key_for_verifying_token_signature

Here is what jwks-rsa implementation looks like.

https://auth0.com/blog/implement-sign-in-with-apple-using-auth0-extensibility/

src/Adapters/Auth/apple.js Show resolved Hide resolved
src/Adapters/Auth/apple.js Show resolved Hide resolved
@chriscborg
Copy link
Contributor

Hi, for those like myself who don’t have the skillset to contribute to this issue (apologies) is there a workaround from iOS or having this fixed is the only way? Because Apple are starting to enforce the iOS13 SDK which would unfortunately mandate the sign in with Apple. Thanks

@dplewis
Copy link
Member

dplewis commented Feb 21, 2020

@chriscborg signin with Apple is already supported. https://docs.parseplatform.org/parse-server/guide/#apple-authdata

This PR is to improve the existing implementation.

Can you post a link about a mandate / require this?

@chriscborg
Copy link
Contributor

@dplewis thanks for the reply. please find the link to the Apple review guidelines mandating the Sign In with Apple if the app uses other social logins https://developer.apple.com/app-store/review/guidelines/#sign-in-with-apple

I am having an issue when doing the sign in with Apple and I thought that it was related to this issue. When I attempt the login, some times, I'm getting the below error from the server. Sometimes it succeeds, sometimes it fails with the below.

error: Uncaught internal server error.invalid signature {"name":"JsonWebTokenError","stack":"JsonWebTokenError: invalid signature\n    at /app/node_modules/jsonwebtoken/verify.js:133:19\n    at getSecret (/app/node_modules/jsonwebtoken/verify.js:90:14)\n    at Object.module.exports [as verify] (/app/node_modules/jsonwebtoken/verify.js:94:10)\n    at verifyIdToken (/app/node_modules/parse-server/lib/Adapters/Auth/apple.js:48:25)\n    at processTicksAndRejections (internal/process/task_queues.js:97:5)\n    at async Promise.all (index 0)"}
JsonWebTokenError: invalid signature
at /app/node_modules/jsonwebtoken/verify.js:133:19
at getSecret (/app/node_modules/jsonwebtoken/verify.js:90:14)
at Object.module.exports [as verify] (/app/node_modules/jsonwebtoken/verify.js:94:10)
at verifyIdToken (/app/node_modules/parse-server/lib/Adapters/Auth/apple.js:48:25)
at processTicksAndRejections (internal/process/task_queues.js:97:5)
at async Promise.all (index 0)

Do you think this is related to this issue or is it something else?

@dplewis
Copy link
Member

dplewis commented Feb 22, 2020

if the app uses other social logins

Ok I though you meant it was required in every app

I’m not sure if this will fix your issue. Feel free to pull down this branch fork and try it in your app. I left a comment above about another implementation for Sign In with Apple that may solve all our issues

@chriscborg
Copy link
Contributor

@dplewis thanks for your suggestion. @andrewking0207 @dplewis I can confirm that after forking this branch, the issue mentioned above was resolved. I look forward to seeing this merged and released. I wish I could help so if there's a way let me know.

@ashish-naik
Copy link

I consistently get nil sessionToken from my server deployed on Heroku because of this i get error 206.

Could that be due to this issue? it works consistently on my local server.

I have tried searching answer for nil token everywhere but no luck.

If this fix will solve the problem then would be great.

@markuswinkler
Copy link

This fixes the problem for me as well. Please merge. :)

@davimacedo
Copy link
Member

@andrewking0207 have you had the chance to look at @dplewis comments?

@andrewking0207
Copy link
Contributor Author

Yes, sorry for the delay. I'll get those changes implemented.

Copy link
Member

@dplewis dplewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the improvements! I added a few comments and the tests look good also.

spec/AuthenticationAdapters.spec.js Outdated Show resolved Hide resolved
src/Adapters/Auth/apple.js Outdated Show resolved Hide resolved
src/Adapters/Auth/apple.js Outdated Show resolved Hide resolved
src/Adapters/Auth/apple.js Outdated Show resolved Hide resolved
@andrewking0207
Copy link
Contributor Author

I think we should be all set here. I'm not sure why it's showing a code coverage change for RestWrite or MongoStorageAdapter, I didn't touch those. Let me know if you want me to add tests for those as part of this PR.

Copy link
Member

@dplewis dplewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry for the constant reviews. Your is code beautiful. I’m just nitpicking.

options.client_id,
options.cacheMaxEntries,
options.cacheMaxAge
);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A quick nit. Functions should have 2 parameters max. Just pass in options.

Also if I pass in { clientID: “something” } you default values would never be set. Use the or operator.

options.cacheMaxEntries || 5 ( if the first expression is false or undefined use the second) just a quick trick for setting defaults.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good feedback thanks. I got that changed.

Copy link
Member

@dplewis dplewis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thanks @andrewking0207 and everybody for testing this.

@dplewis dplewis merged commit 8e0e485 into parse-community:master Mar 11, 2020
@benpackard
Copy link

Excited for this one, going to roll it out to all of my clients that use Sign In with Apple ASAP. Thanks for everyone's work on this!

@chriscborg
Copy link
Contributor

Thank you @andrewking0207 and @dplewis for your work on this. This is going to be extremely helpful to a majority of our apps!

@oallouch
Copy link
Contributor

Here too. Thx a lot.

@mmimeault
Copy link

mmimeault commented Mar 19, 2020

Thank you for the fix! Works way better now.
But thank you for the initial version @dplewis ;)

@benpackard
Copy link

Any thoughts on when we might see a new release with this change? I have a couple of projects I’m eager to update but I know it’s a busy time for all.

UnderratedDev pushed a commit to UnderratedDev/parse-server that referenced this pull request Mar 21, 2020
* use token and algo from jwt header

* change node-rsa out for jwks-rsa, reflect change in tests and add one test for coverage

* remove superfluous cache, allow jwks cache parameters to be passed to validateAuthData

* remove package lock

* regenerate package lock

* try fixing package-lock with copy from master

* manual changes for merge conflict

* whitespace

* pass options as object

* fix inconsistent variable name
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 this pull request may close these issues.

Sign in With Apple token verification fails on occassion
9 participants