테스트 사이트 - 개발 중인 베타 버전입니다

소셜 애플로그인 연동 채택완료

hazkiryo 5년 전 조회 4,184

</p>

<p><?php



/*!

* Hybridauth

* <a href="https://hybridauth.github.io" target="_blank" rel="noopener noreferrer">https://hybridauth.github.io</a> | <a href="https://github.com/hybridauth/hybridauth" target="_blank" rel="noopener noreferrer">https://github.com/hybridauth/hybridauth</a>

*  (c) 2020 Hybridauth authors | <a href="https://hybridauth.github.io/license.html" target="_blank" rel="noopener noreferrer">https://hybridauth.github.io/license.html</a>

*/</p>

<p>

class Hybrid_Providers_Apple extends Hybrid_Provider_Model_OAuth2

{    

    public $scope = "name email";

    public $AuthorizeUrlParametersEncType = "PHP_QUERY_RFC3986";

    

    /**

    * initialization

    */

    function initialize()

    {

        parent::initialize();</p>

<p>        // Provider API end-points

        $this->api->api_base_url  = "<a href="https://appleid.apple.com/auth/";" target="_blank" rel="noopener noreferrer">https://appleid.apple.com/auth/";</a>

        $this->api->authorize_url = "<a href="https://appleid.apple.com/auth/authorize";" target="_blank" rel="noopener noreferrer">https://appleid.apple.com/auth/authorize";</a>

        $this->api->access_token_url = "<a href="https://appleid.apple.com/auth/token";" target="_blank" rel="noopener noreferrer">https://appleid.apple.com/auth/token";</a>

        $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);

        }</p>

<p>        // 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();

    }</p>

<p>    /**

     * {@inheritdoc}

     *

     * include id_token $tokenNames

     */

    function getAccessToken()

    {

        $tokenNames = [

            'access_token',

            'id_token',

            'access_token_secret',

            'token_type',

            'refresh_token',

            'expires_in',

            'expires_at',

        ];</p>

<p>        $tokens = [];</p>

<p>        foreach ($tokenNames as $name) {

            if ($this->getStoredData($name)) {

                $tokens[$name] = $this->getStoredData($name);

            }

        }</p>

<p>        return $tokens;

    }</p>

<p>    /**

     * {@inheritdoc}

     */

    function validateAccessTokenExchange($response)

    {

        $collection = parent::validateAccessTokenExchange($response);</p>

<p>        $this->storeData('id_token', $collection->get('id_token'));</p>

<p>        return $collection;

    }</p>

<p>    function getUserProfile()

    {

        $id_token = $this->getStoredData('id_token');</p>

<p>        $verifyTokenSignature =

            ($this->config->exists('verifyTokenSignature')) ? $this->config->get('verifyTokenSignature') : true;</p>

<p>        if (!$verifyTokenSignature) {

            // payload extraction by <a href="https://github.com/omidborjian" target="_blank" rel="noopener noreferrer">https://github.com/omidborjian</a>

            // <a href="https://github.com/hybridauth/hybridauth/issues/1095#issuecomment-626479263" target="_blank" rel="noopener noreferrer">https://github.com/hybridauth/hybridauth/issues/1095#issuecomment-626479263</a>

            // 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');</p>

<p>            \Firebase\JWT\JWT::$leeway = 120;</p>

<p>            foreach ($publicKeys->keys as $publicKey) {

                try {

                    $rsa = new RSA();

                    $jwk = (array)$publicKey;</p>

<p>                    $rsa->loadKey(

                        [

                            'e' => new BigInteger(base64_decode($jwk['e']), 256),

                            'n' => new BigInteger(base64_decode(strtr($jwk['n'], '-_', '+/'), true), 256)

                        ]

                    );

                    $pem = $rsa->getPublicKey();</p>

<p>                    $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);

            }

        }</p>

<p>        $data = new Data\Collection($payload);</p>

<p>        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'));</p>

<p>        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]);

            }

        }</p>

<p>        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'));</p>

<p>        $this->user->profile->sid         = get_social_convert_id( $this->user->profile->identifier, $this->providerId );</p>

<p>        return $this->user->profile;

        

        

    }</p>

<p>    /**

     * @return 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.'

            );

        }</p>

<p>        // 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.'

            );

        }</p>

<p>        // 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.'

            );

        }</p>

<p>        // Find the 10-char Key ID value from the portal

        $key_content = $this->config->filter('keys')->get('key_content');</p>

<p>        // 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.'

                );

            }</p>

<p>            if (!file_exists($key_file)) {

                throw new InvalidApplicationCredentialsException(

                    "Your key file $key_file does not exist."

                );

            }</p>

<p>            $key_content = file_get_contents($key_file);

        }</p>

<p>        $data = [

            'iat' => time(),

            'exp' => time() + 86400 * 180,

            'iss' => $team_id,

            'aud' => '<a href="https://appleid.apple.com'," target="_blank" rel="noopener noreferrer">https://appleid.apple.com',</a>

            'sub' => $client_id

        ];</p>

<p>        $secret = JWT::encode($data, $key_content, 'ES256', $key_id);</p>

<p>        return $secret;

    }

}</p>

<p>

 

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

                );</p>

<p>

 

 

 

 

댓글을 작성하려면 로그인이 필요합니다.

답변 1개

채택된 답변
+20 포인트
5년 전
로그인 후 평가할 수 있습니다

답변에 대한 댓글 1개

h
hazkiryo
5년 전
넵 ㅠㅠ

댓글을 작성하려면 로그인이 필요합니다.

답변을 작성하려면 로그인이 필요합니다.

로그인