Sign in with Apple (iOS App + Backend verification) API returns error “invalid_client”

南楼画角 提交于 2020-02-01 03:52:25

问题


I'm trying to implement Sign In with Apple with an iOS app and a backend. The goal is this:

  1. The User signs in on the iOS app
  2. After a positive response the app calls an endpoint on the backend and hands over the authorizationCode
  3. The backend now needs to verify the authorizationCode with another call to apple's server.

Here I'm confused. In order to make this call, the backend needs to provide a bunch of parameters:

URL

https://appleid.apple.com/auth/token

Query Parameters

client_id     = com.mycompany.appname
client_secret = ...
code          = ... // `authorizationCode` from the signin in the iOS app
grant_type    = authorization_code

I've generated a JWT for the client_secret:

JWT Properties

header:
    kid: <key id, created on Apple Dev Portal>
claims:
    iss: <team id>
    iat: <current timestamp>
    exp: <current timestamp + 180 days>
    aud: "https://appleid.apple.com"
    sub: "com.mycompany.appname"

Yesterday I've created two keys for two apps (A and B) on the Dev Portal, used it to generate secrets and today app A worked and I've got a positive response:

Positive response

{
    "access_token" : "a1e64327924yt49f5937d643e25a48b81.0.mxwz.GN9TjJIJ5_4dR6WjbZoVNw",
    "token_type" : "Bearer", 
    "expires_in" : 3600, 
    "refresh_token" : "rca76d9ebta644fde9edba269c61eeb41.0.mxwz.sMDUlXnnLLUOu2z0WlABoQ", 
    "id_token" : "eyJraWQiOiJBSURPUEsxIcccYWxnIjoiUlMyNTYifQ.eyJpc3MiOiJodHRwczovL2FwcGxlaWQuYXBwbGUuY29tIiwiYXVkIjoiZGUudHJ1ZmZscy5hcHBsZS1zaWduaW4tdGVzdCIsImV4cCI6MTU2NzcwMDI0MiwiaWF0IjoxNTY3Njk5NjQyLCJzdWaaaiIwMDA3NjkuYWY3NDdjMTlmZGRmNDJhNjhhYmFkZjhlNTQ1MmY3NjAuMjIwNSIsImF0X2hhc2giOiJrVThQTkZOUHYxS0RGUEtMT2hIY213IiwiYXV0aF90aW1lIjoxNTY3Njk5NjM5fQ.g3JD2MDGZ6wiVS9VMHpj24ER0XqJlunatmqpE7sRarMkhMHMTk7j8gty1lpqVBC6Z8L5CZuewdzLuJ5Odrd3_c1cX7gparTQE4jCyvyTACCPKHXReTC2hGRIEnAogcxv6HDWrtZgb3ENhoGhZW778d70DUdd-e4KKiAvzLOse-endHr51PaR1gv-cHPcwnm3NQZ144I-xhpU5TD9VQJ9IgLQvZGZ8fi8SOcu6rrk5ZOr0mpt0NbJNGYgH5-8iuSxo18QBWZDXoEGNsa4kS5GDkq5Cekxt7JsJFc_L1Np94giXhpbYHqhcO1pZSGFrJVaMvMMftZfuS_T3sh2yCqkcA"
}

B, however, still doesn't work. Today I revoked the key for A and created a new one and now it doesn't work anymore with the new one, but still with the old one, even though I deleted it on the Dev Portal. I'm so confused.

Response Error:

{
    "error": "invalid_client"
}

I wonder if Apple needs some time indexing or something like that. I just want to understand how this works.


回答1:


There are several reasons why it could happen:

  1. client_id for web should be Service id. For apps it should be App bundle id. (Even if you use native apple dialog get code and later pass it to a webserver and then use it to request token API.) sub in JWT call should be the same as client_id. See the answer there Apple forum
  2. Your JWT library does not support encryption required by Apple sign-in. They use the JWT standard for this, using an elliptic curve algorithm with a P-256 curve and SHA256 hash. In other words, they use the ES256 JWT algorithm. Some JWT libraries don’t support elliptic curve methods, so make sure yours does before you start trying this out. ES256 and invalid_client
  3. Dates in token. Try to set the following
 expires: DateTime.UtcNow.AddDays(2), // expiry can be a maximum of 6 months
 issuedAt: DateTime.UtcNow.AddDays(-1),
 notBefore: DateTime.UtcNow.AddDays(-1),

It failed with invalid_client on my webserver, since Apple considered it as a certificate from the future, when I had:

 expires: DateTime.UtcNow.AddMinutes(5), // expiry can be a maximum of 6 months
 issuedAt: DateTime.UtcNow,
 notBefore: DateTime.UtcNow,

It's also important to specify the User-Agent header when you call the token API. It's also worth mentioning that curl can throw this error, while it will work fine when you call it from a web server.




回答2:


Your native APP ID is your bundle ID prefixed with your team ID, seperated by a comma.

"The Apple App ID is a two part string used to identify one or more apps. Specifically, the Apple app ID is your team ID and bundle ID joined with a period, for example: 1A234H7ABC.com.yourdomain.YourApp."

I'm having the same issue getting this to work however.



来源:https://stackoverflow.com/questions/57809927/sign-in-with-apple-ios-app-backend-verification-api-returns-error-invalid-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!