使用Apple登录的invalid_client [英] invalid_client for sign in with apple

查看:1797
本文介绍了使用Apple登录的invalid_client的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图实现的目标:

  • iOS client sends a JWT token to the backend.
  • Backend (Java) calls https://appleid.apple.com/auth/token to verify the token.

我到目前为止有什么:

拨打Apple验证电话:

to make Apple verification call:

        restTemplate = new RestTemplate();

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
        MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
        map.add("client_id", clientId); // app_id like com.app.id
        String token = generateJWT();   // generated jwt
        map.add("client_secret", token); 
        map.add("grant_type", "authorization_code");
        map.add("code", authorizationCode);  // JWT code we got from iOS
        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(map, headers);

        final String appleAuthURL = "https://appleid.apple.com/auth/token";
        String response = restTemplate.postForObject(appleAuthURL, request, String.class);

代币生成:

        final PrivateKey privateKey = getPrivateKey();
        final int expiration = 1000 * 60 * 5;

        String token = Jwts.builder()
                .setHeaderParam(JwsHeader.KEY_ID, keyId) // key id I got from Apple 
                .setIssuer(teamId)  
                .setAudience("https://appleid.apple.com")
                .setSubject(clientId) // app id com.app.id
                .setExpiration(new Date(System.currentTimeMillis() + expiration))
                .setIssuedAt(new Date(System.currentTimeMillis()))
                .signWith(SignatureAlgorithm.ES256, privateKey) // ECDSA using P-256 and SHA-256
                .compact();

        return token;

从文件中获取我的私钥:

to get my private key from the file:

        final Reader pemReader = new StringReader(getKeyData());
        final PEMParser pemParser = new PEMParser(pemReader);
        final JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
        final PrivateKeyInfo object = (PrivateKeyInfo) pemParser.readObject();
        final PrivateKey pKey = converter.getPrivateKey(object);

我确认我的JWT具有所有必填字段:

I confirmed my JWT has all required fields:

{
  "kid": "SAME KEY AS MY KEY ID",
  "alg": "ES256"
}

{
  "iss": "Blahblah",
  "aud": "https://appleid.apple.com",
  "sub": "com.app.id",
  "exp": 1578513833,
  "iat": 1578513533
}

推荐答案

此行引起了我的注意:

map.add("code", authorizationCode);  // JWT code we got from iOS

authorizationCode不是jwt

JSON Web令牌由3个部分组成,这些部分由点分隔

JSON Web Tokens consist of 3 parts separated by dots

,但是authorizationCode具有以下4个部分:

but the authorizationCode has 4 parts like this:

text1.text2.0.text3

您可能正在使用iOS应用中的identityToken而不是authorizationCode

You are probably using the identityToken from the iOS app instead of the authorizationCode

这是您检索它的方式:

let authorizationCode = String(data: appleIDCredential.authorizationCode!, encoding: .utf8)!
print("authorizationCode: \(authorizationCode)")

对于那些在遇到相同的invalid_client错误后可能会来到这里的人,也要谨记以下几点:

Also good to have the following in mind for those who might come here after getting the same invalid_client error:

  1. 孩子是来自developer.apple.com/account/resources/authkeys/list

  1. kid is the id for the private key from developer.apple.com/account/resources/authkeys/list

keyFile是保存从developer.apple.com

keyFile is the file holding the private key downloaded from developer.apple.com

teamID,可以在右上角看到teamID

teamID can be found by logging in to developer.apple.com and clicking on account, the teamID can be seen in the upper right corner

以aud为单位的值应为 https://appleid.apple.com

the value in aud should be https://appleid.apple.com

app_id是应用程序的捆绑包标识符

app_id is the bundle identifier for the app

以防万一,在python中,这是一个可行的解决方案,用于创建client_secret:

In case it might help, here is a working solution in python to create a client_secret:

# $ pip install pyjwt
import jwt
import time

kid = "myKeyId"  
keyFile = "/pathToFile/AuthKey.p8"
key = ""
with open(keyFile, 'r') as myFile:
    key = myFile.read()

print(key)

timeNow = int(round(time.time()))
time3Months = timeNow + 86400*90

claims = {
    'iss': teamID,
    'iat': timeNow,
    'exp': time3Months,
    'aud': 'https://appleid.apple.com',
    'sub': app_id,
}


secret = jwt.encode(claims, key, algorithm='ES256', headers={'kid': kid})
print("secret:")
print(secret)
client_secret = secret.decode("utf-8")
print(client_secret)

这篇关于使用Apple登录的invalid_client的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆