更新时间:2022-10-15 10:54:49
可能发生的原因有几个:
client_id
应该是 Service id.对于apps,它应该是App bundle id.(即使您使用原生苹果对话框获取 code
并稍后将其传递给网络服务器,然后使用它来请求令牌 API.) JWT 调用中的 sub
应该与client_id
.在苹果论坛查看答案
expires: DateTime.UtcNow.AddDays(2),//有效期最长为 6 个月发布时间:DateTime.UtcNow.AddDays(-1),notBefore: DateTime.UtcNow.AddDays(-1),
我的网络服务器上的 invalid_client 失败了,因为 Apple 认为它是未来的证书,当时我有:
expires: DateTime.UtcNow.AddMinutes(5),//有效期最长为 6 个月发布时间:DateTime.UtcNow,notBefore: DateTime.UtcNow,
Content-Type: application/x-www-form-urlencoded
标头,而不是某些库的 Content-Type: application/json
比如默认设置的axios.I'm trying to implement Sign In with Apple with an iOS app and a backend. The goal is this:
authorizationCode
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.
There are several reasons why it could happen:
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
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,
Content-Type: application/x-www-form-urlencoded
header instead of Content-Type: application/json
that some libraries like axios set by default.