J'ai implémenté le côté application de la nouvelle fonctionnalité Apple "Se connecter avec Apple", mais je ne suis pas en mesure de vérifier avec le code d'autorisation dans mon backend. Mon backend est écrit en Java et je ne peux pas générer de JWT et communiquer avec Apple.
J'ai aussi eu une erreur mais après quelques réglages, son fonctionnement, retrouvez mon Tweak ci-dessous, note, c'est en kotlin
private suspend fun getPrivateKey(): Status {
return awaitBlocking {
val authKeyFile = appleConfig.getString("auth_private_key_file", "")
val authTokenFilePath = getDataDir()!!.resolve(authKeyFile).absolutePath
val pemParser = PEMParser(FileReader(authTokenFilePath))
val converter = JcaPEMKeyConverter()
val obj = pemParser.readObject() as PrivateKeyInfo
val privateKey = converter.getPrivateKey(obj)
successStatus(data = privateKey)
}
}
/**
* generateSecretKey
*/
suspend fun generateSecretKey() : Status{
val getAuthPrivateKey = getPrivateKey()
if(getAuthPrivateKey.isError()){
logger.fatal(getAuthPrivateKey.message)
return errorStatus("system_busy")
}
val privateKeyData = getAuthPrivateKey.getData<PrivateKey>()
val clientId = "com.company.app"
//team id found in Apple developer portal
val teamId = appleConfig.getString("team_id","")
//Apple sign in key ID found in app developer portal
val authKeyId = appleConfig.getString("auth_key_id","")
val header = mutableMapOf<String,Any>(
"alg" to "E256",
"kid" to authKeyId
)
val now = Instant.now().epochSecond
val claims = mutableMapOf<String,Any>(
"iss" to teamId,
"iat" to now,
"exp" to now + 86400*180,
"aud" to "https://appleid.Apple.com",
"sub" to clientId
)
println("header - $header")
println("claims - $claims")
val token = Jwts.builder()
.setHeader(header)
.setClaims(claims)
.signWith(privateKeyData,SignatureAlgorithm.ES256)
.compact();
return successStatus(data = token)
} //end fun
/**
* fetchApplePublicKeys
*/
private suspend fun fetchAccessToken(authInfo: JsonObject): Status {
return try{
val authCode = authInfo.getString("auth_code")
val clientIdToken = authInfo.getString("id_token")
val accessTokenEndpoint =
appleConfig.getString("access_token_endpoint")
val secretKeyTokenStatus = generateSecretKey()
if(secretKeyTokenStatus.isError()){
logger.fatal(secretKeyTokenStatus.message)
return errorStatus("system_busy")
}
val clientSecret = secretKeyTokenStatus.getData<String>()
val redirectUrl = ""
val clientId = appleConfig.getString("client_id")
val formData = MultiMap.caseInsensitiveMultiMap()
formData.add("client_secret",clientSecret)
.add("client_id",clientId)
.add("redirect_uri",redirectUrl)
.add("grant_type","authorization_code")
.add("code",authCode)
println("accessTokenEndpoint - $accessTokenEndpoint")
println("formData - $formData")
val responseData = httpClient(this::class)
.postAbs(accessTokenEndpoint)
.putHeader("Content-Type","application/x-www-form-urlencoded")
.sendFormAwait(formData)
.bodyAsJsonObject()
println("responseData - ${responseData}")
if(responseData.containsKey("error")){
logger.fatal(responseData.getString("error"))
return errorStatus("social_auth_failed")
}
//val responseIdToken = responseData.getString("id_token","")
return successStatus(data = responseData)
} catch (e: Exception){
logger.fatal(e.message,e)
errorStatus("system_busy")
}
}