Sign in with Apple Java User Verification

前端 未结 2 2233
暖寄归人
暖寄归人 2020-12-09 19:11

I\'ve implemented the app side of the new apple feature \"Sign in with Apple\" but i\'m unable to verificate with authorizationCode in my backend. My backend is written in j

2条回答
  •  半阙折子戏
    2020-12-09 19:56

    I had an error too but after some tweaks, its working, find my tweak below, note, its in 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()
    
        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(
                "alg" to "E256",
                "kid" to authKeyId
        )
    
        val now = Instant.now().epochSecond
    
        val claims = mutableMapOf(
                "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()
    
            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")
        }
    }
    

提交回复
热议问题