본문으로 바로가기

php 애플(apple) sns 연동하기

category IT/언어 2023. 6. 5. 14:25
반응형

의외로 sns 연동 하는게 php 모듈로 이용 하는게 쉽지는 않습니다.

compser 로 설치 해서 하라고는 하는데 그거 사용 할려고 설치 해 보면 사용법이 너무 힘듭니다.

다른 sns 계정들은 소스가 좀 있는데 애플 연동 php 는 없는거 같아서 만들어 보았습니다.

 

return url 에서 토큰 값을 가지고 애플의 snsid 를 가져 오는 부분 입니다.

 

요청 하는 부분은 네이버나 카카오 와 같습니다.

 

getToken 이라는 함수만 호출 하면 해당 하는 값이 나오는 구조 입니다.

 

애플과 연동 할려면 필요한 값들이 4 개 있습니다.

 

애플개발자 keyId

애플개발자 teamId

애플개발자 clientId

애플개발자AuthKey_***.pem

 

위 4 가지는 애플 개발자센터에 값을 가져 올 수 있습니다.

 

소스에서 애플개발자AuthKey 의 위치는 절대경로에 올리고 그 위치로 설정해 주시면 됩니다.

 

아래는 소스 입니다.

<?php
	$buttonUrl = "https://appleid.apple.com/auth/authorize";
	$tokenUrl = "https://appleid.apple.com/auth/token";
	
	$response = getToken("return url 에서 받은  token 값");
	ptrint_r($response);
	function getToken($getToken) {

		$client_secret = generateJWTClientSecretForApple(애플개발자 keyId , 애플개발자 teamId, 애플개발자 clientId);        

		$response = callUrlForApple('https://appleid.apple.com/auth/token', array(
						'grant_type' => 'authorization_code',
						'code' => 받은토큰값,
						//'redirect_uri' => $redirect_uri,
						'client_id' => 애플개발자 클라이언트아이디,
						'client_secret' => $client_secret,
						));

		return $response; // 이 값을 가지고 판단 한다.

	}

	/** 애플 관련 */
    function callUrlForApple($url, $params=false) {
		$ch = curl_init($url);
		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
		if($params) curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($params));
		curl_setopt($ch, CURLOPT_HTTPHEADER, array(
		'Accept: application/json',
		'User-Agent: curl', # Apple requires a user agent header at the token endpoint
		));
		$response = curl_exec($ch);
		return json_decode($response);
	}
    
    function encodeForApple($data) {
        $encoded = strtr(base64_encode($data), '+/', '-_');
        return rtrim($encoded, '=');
    }
    
    function generateJWTClientSecretForApple($kid, $iss, $sub) {        
        $header = array(
            'alg' => 'ES256',
            'kid' => $kid
        );
        $body = array(
            'iss' => $iss,
            'iat' => time(),
            'exp' => time() + 3600,
            'aud' => 'https://appleid.apple.com',
            'sub' => $sub
        );        
        
        $privKey = openssl_pkey_get_private(file_get_contents('애플개발자AuthKey_***.pem 의 위치'));
        if (!$privKey){
            echo "no privKey";
            return false;
        }
    
        $payload = encodeForApple(json_encode($header)).'.'.encodeForApple(json_encode($body));
        $signature = '';
        $success = openssl_sign($payload, $signature, $privKey, "SHA256");
        if (!$success) {
            echo "openssl_sign error";
            return false;
        }
    
        $raw_signature = signatureFromDERForApple($signature, 256);
        //$raw_signature = fromDER($signature, 256);  // 이거 안 된다 이유는 모름
        return $payload.'.'.encodeForApple($raw_signature);
    }
    
    function readDERForApple($der, $offset = 0)
    {
        $pos = $offset;
        $size = strlen($der);
        $constructed = (ord($der[$pos]) >> 5) & 0x01;
        $type = ord($der[$pos++]) & 0x1f;
    
        // Length
        $len = ord($der[$pos++]);
        if ($len & 0x80) {
            $n = $len & 0x1f;
            $len = 0;
            while ($n-- && $pos < $size) {
                $len = ($len << 8) | ord($der[$pos++]);
            }
        }
            
        // Value
        if ($type == ASN1_BIT_STRING) {
            $pos++; // Skip the first contents octet (padding indicator)
            $data = substr($der, $pos, $len - 1);
            $pos += $len - 1;
        } elseif (!$constructed) {
            $data = substr($der, $pos, $len);
            $pos += $len;
        } else {
            $data = null;
        }
    
        return array($pos, $data);
    }
    
    function signatureFromDERForApple($der, $keySize)
    {
        // OpenSSL returns the ECDSA signatures as a binary ASN.1 DER SEQUENCE
        list($offset, $_) = readDERForApple($der);
        list($offset, $r) = readDERForApple($der, $offset);
        list($offset, $s) = readDERForApple($der, $offset);
    
        // Convert r-value and s-value from signed two's compliment to unsigned
        // big-endian integers
        $r = ltrim($r, "x00");
        $s = ltrim($s, "x00");
    
        // Pad out r and s so that they are $keySize bits long
        $r = str_pad($r, $keySize / 8, "x00", STR_PAD_LEFT);
        $s = str_pad($s, $keySize / 8, "x00", STR_PAD_LEFT);
    
        return $r . $s;
    }

 

 

 

반응형