소셜 애플로그인 연동

소셜 애플로그인 연동

QA

소셜 애플로그인 연동

본문


<?php
/*!
* Hybridauth
* https://hybridauth.github.io | https://github.com/hybridauth/hybridauth
*  (c) 2020 Hybridauth authors | https://hybridauth.github.io/license.html
*/

class Hybrid_Providers_Apple extends Hybrid_Provider_Model_OAuth2
{    
    public $scope = "name email";
    public $AuthorizeUrlParametersEncType = "PHP_QUERY_RFC3986";
    
    /**
    * initialization
    */
    function initialize()
    {
        parent::initialize();
        // Provider API end-points
        $this->api->api_base_url  = "https://appleid.apple.com/auth/";
        $this->api->authorize_url = "https://appleid.apple.com/auth/authorize";
        $this->api->access_token_url = "https://appleid.apple.com/auth/token";
        $this->AuthorizeUrlParameters['response_mode'] = "form_post";
        
        if (!$this->config["keys"]["id"] || !$this->config["keys"]["secret"]) {
            throw new Exception("Your application id and secret are required in order to connect to {$this->providerId}.", 4);
        }
        // redirect uri mismatches when authenticating with Apple.
        if (isset($this->config['redirect_uri']) && !empty($this->config['redirect_uri'])) {
            $this->api->redirect_uri = $this->config['redirect_uri'];
        }
    }
    
    /**
     * {@inheritdoc}
     */
    function configure()
    {
        $keys = $this->config->get('keys');
        $keys['secret'] = $this->getSecret();
        $this->config->set('keys', $keys);
        return parent::configure();
    }
    /**
     * {@inheritdoc}
     *
     * include id_token $tokenNames
     */
    function getAccessToken()
    {
        $tokenNames = [
            'access_token',
            'id_token',
            'access_token_secret',
            'token_type',
            'refresh_token',
            'expires_in',
            'expires_at',
        ];
        $tokens = [];
        foreach ($tokenNames as $name) {
            if ($this->getStoredData($name)) {
                $tokens[$name] = $this->getStoredData($name);
            }
        }
        return $tokens;
    }
    /**
     * {@inheritdoc}
     */
    function validateAccessTokenExchange($response)
    {
        $collection = parent::validateAccessTokenExchange($response);
        $this->storeData('id_token', $collection->get('id_token'));
        return $collection;
    }
    function getUserProfile()
    {
        $id_token = $this->getStoredData('id_token');
        $verifyTokenSignature =
            ($this->config->exists('verifyTokenSignature')) ? $this->config->get('verifyTokenSignature') : true;
        if (!$verifyTokenSignature) {
            // payload extraction by https://github.com/omidborjian
            // https://github.com/hybridauth/hybridauth/issues/1095#issuecomment-626479263
            // JWT splits the string to 3 components 1) first is header 2) is payload 3) is signature
            $payload = explode('.', $id_token)[1];
            $payload = json_decode(base64_decode($payload));
        } else {
            // validate the token signature and get the payload
            $publicKeys = $this->apiRequest('keys');
            \Firebase\JWT\JWT::$leeway = 120;
            foreach ($publicKeys->keys as $publicKey) {
                try {
                    $rsa = new RSA();
                    $jwk = (array)$publicKey;
                    $rsa->loadKey(
                        [
                            'e' => new BigInteger(base64_decode($jwk['e']), 256),
                            'n' => new BigInteger(base64_decode(strtr($jwk['n'], '-_', '+/'), true), 256)
                        ]
                    );
                    $pem = $rsa->getPublicKey();
                    $payload = JWT::decode($id_token, $pem, ['RS256']);
                    $error = false;
                    break;
                } catch (\Exception $e) {
                    $error = $e->getMessage();
                    if ($e instanceof \Firebase\JWT\ExpiredException) {
                        break;
                    }
                }
            }
            if ($error) {
                throw new \Exception($error);
            }
        }
        $data = new Data\Collection($payload);
        if (!$data->exists('sub')) {
            throw new UnexpectedValueException('Missing token payload.');
        }
        
        /*$userProfile = new User\Profile();
        $userProfile->identifier = $data->get('sub');
        $userProfile->email = $data->get('email');
        $this->storeData('expires_at', $data->get('exp'));
        if (!empty($_REQUEST['user'])) {
            $objUser = json_decode($_REQUEST['user']);
            $user = new Data\Collection($objUser);
            if (!$user->isEmpty()) {
                $name = $user->get('name');
                $userProfile->firstName = $name->firstName;
                $userProfile->lastName = $name->lastName;
                $userProfile->displayName = join(' ', [$userProfile->firstName, $userProfile->lastName]);
            }
        }
        return $userProfile;*/
        
        # store the user profile.  
        $this->user->profile->identifier = $data->get('sub');
        $this->user->profile->email = $data->get('email');
        $this->storeData('expires_at', $data->get('exp'));
        $this->user->profile->sid         = get_social_convert_id( $this->user->profile->identifier, $this->providerId );
        return $this->user->profile;
        
        
    }
    /**
     *  string secret token
     */
    private function getSecret()
    {
        
        // Your 10-character Team ID
        if (!$team_id = $this->config->filter('keys')->get('team_id')) {
            throw new InvalidApplicationCredentialsException(
                'Missing parameter team_id: your team id is required to generate the JWS token.'
            );
        }
        // Your Services ID, e.g. com.aaronparecki.services
        if (!$client_id = $this->config->filter('keys')->get('id') ?: $this->config->filter('keys')->get('key')) {
            throw new InvalidApplicationCredentialsException(
                'Missing parameter id: your client id is required to generate the JWS token.'
            );
        }
        // Find the 10-char Key ID value from the portal
        if (!$key_id = $this->config->filter('keys')->get('key_id')) {
            throw new InvalidApplicationCredentialsException(
                'Missing parameter key_id: your key id is required to generate the JWS token.'
            );
        }
        // Find the 10-char Key ID value from the portal
        $key_content = $this->config->filter('keys')->get('key_content');
        // Save your private key from Apple in a file called `key.txt`
        if (!$key_content) {
            if (!$key_file = $this->config->filter('keys')->get('key_file')) {
                throw new InvalidApplicationCredentialsException(
                    'Missing parameter key_content or key_file: your key is required to generate the JWS token.'
                );
            }
            if (!file_exists($key_file)) {
                throw new InvalidApplicationCredentialsException(
                    "Your key file $key_file does not exist."
                );
            }
            $key_content = file_get_contents($key_file);
        }
        $data = [
            'iat' => time(),
            'exp' => time() + 86400 * 180,
            'iss' => $team_id,
            'aud' => 'https://appleid.apple.com',
            'sub' => $client_id
        ];
        $secret = JWT::encode($data, $key_content, 'ES256', $key_id);
        return $secret;
    }
}

 

https://github.com/hybridauth/hybridauth/blob/master/src/Provider/Apple.php

 

애플로그인 연동을 위해 위 파일을 그누보드에 맞게 initialize와 getUserProfile만 위 소스와 같이 조금 수정해줬는데 아이디 비밀번호 쓰는창이 나오고 로그인까지는 되는데 그 이 후에

 

"사용자 프로필 요청이 실패했습니다.사용자가 해당 서비스에 연결되어 있지 않을 경우도 있습니다. 이 경우 다시 인증 요청을 해야 합니다."

 

이렇게 에러가 뜨는데 혹시 어디가 잘못된걸까요? 몇주째 해결하지 못하고 있네요

 

혹시 그누보드에 애플로그인 연동하신분이 계시다면 도움 부탁드립니다!

 

/plugin/social/includes/functions.php 경로에 provider는 추가했습니다.

 


        // Apple
        $r['Apple'] = array(
                    "enabled" => option_array_checked('apple', $config['cf_social_servicelist']) ? true : false,
                    "keys" => array("id" => $config['cf_apple_clientid'], "secret" => $config['cf_apple_secret']),
                    "redirect_uri" => get_social_callbackurl('apple'),
                    "trustForwarded" => false
                );

 

 

 

 

이 질문에 댓글 쓰기 :

답변을 작성하시기 전에 로그인 해주세요.
전체 123,503 | RSS
QA 내용 검색

회원로그인

(주)에스아이알소프트 / 대표:홍석명 / (06211) 서울특별시 강남구 역삼동 707-34 한신인터밸리24 서관 1404호 / E-Mail: admin@sir.kr
사업자등록번호: 217-81-36347 / 통신판매업신고번호:2014-서울강남-02098호 / 개인정보보호책임자:김민섭(minsup@sir.kr)
© SIRSOFT