소셜 애플로그인 연동 채택완료
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개
답변을 작성하려면 로그인이 필요합니다.
로그인