Skip to content

Instantly share code, notes, and snippets.

@PeterZhukov
Last active February 7, 2026 13:09
Show Gist options
  • Select an option

  • Save PeterZhukov/47d900e7956fdcf0459169e9cd2e1361 to your computer and use it in GitHub Desktop.

Select an option

Save PeterZhukov/47d900e7956fdcf0459169e9cd2e1361 to your computer and use it in GitHub Desktop.
Yii2 Sign In With Apple

Что это

Мы внедряли Sign In With Apple на сайте, здесь инструкция для PHP для внедрения кнопки Sign In Witn Apple на сайт в фреймворке Yii 2

Пакеты

yiisoft/yii2-authclient - поддержка OAuth 2 в Yii 2

firebase/php-jwt - Apple использует JWT токены

<?php
namespace frontend\auth;
use Firebase\JWT\JWK;
use Firebase\JWT\JWT;
use Yii;
use yii\authclient\OAuth2;
class AppleAuthClient extends OAuth2
{
public $authUrl = 'https://appleid.apple.com/auth/authorize';
public $tokenUrl = 'https://appleid.apple.com/auth/token';
public $keysUrl = 'https://appleid.apple.com/auth/keys';
public $teamId;
public $keyId;
public $keyFile;
public function buildAuthUrl(array $params = [])
{
$params = array_merge($params, [
'response_mode' => 'form_post',
]);
return parent::buildAuthUrl($params);
}
public function fetchAccessToken($authCode, array $params = [])
{
//Генерируем clientSecret
$payload = [
'iat' => time(),
'exp' => time() + 3600,
'iss' => $this->teamId,
'aud' => 'https://appleid.apple.com',
'sub' => $this->clientId,
];
$key = file_get_contents($this->keyFile);
$this->clientSecret = JWT::encode($payload, $key, 'ES256', $this->keyId);
//Получаем токен
return parent::fetchAccessToken($authCode, $params);
}
protected function initUserAttributes()
{
//Запрашиваем Public keys от Apple, чтобы валидировать токен
$request = $this->createRequest()
->setUrl($this->keysUrl);
$response = $this->sendRequest($request);
$publicKeys = JWK::parseKeySet($response);
//Получаем пользовательские данные из закодированного JWT токена
$userData = JWT::decode($this->getAccessToken()->params['id_token'], $publicKeys, ['RS256']);
$userData = (array)$userData;
//Если в POST тоже были данные пользователя, то добавляем их к текущим данным.
if (Yii::$app->request->post('user')) {
$user = json_decode(Yii::$app->request->post('user'), true);
if (!empty($user['name']['firstName'])) {
$userData['first_name'] = $user['name']['firstName'];
}
if (!empty($user['name']['lastName'])) {
$userData['last_name'] = $user['name']['lastName'];
}
if (!empty($user['email'])) {
$userData['post_email'] = $user['email'];
}
}
return $userData;
}
}
return [
'components' => [
'authClientCollection' => [
'class' => 'yii\authclient\Collection',
'clients' => [
'apple' => [
'class' => \frontend\auth\AppleAuthClient::class, //см файл ниже
//client_id и т.д. создается на сайте Apple Developers, лучше обратиться к разработчику под IOS, чтобы он создал
//можно посмотреть кучу инструкций как это делается в интернете или ютубе по запросу Sign In With Apple service id,
//sign in with apple ceate application, sign in with apple step by step и т.д.
// https://www.youtube.com/watch?v=UafqYgRoIC0&ab_channel=Fireship
'clientId' => 'ваш client_id, сайт Apple Developers',
'teamId' => 'ваш team_id, сайт Apple Developers',
'keyId' => 'ваш key_id, сайт Apple Developers',
'keyFile' => Yii::getAlias('@common/files/AuthKeyFile_KeyId.p8'), //сюда положить файл ключа с сайта Apple Developers
//returnUrl обрабатывается классом yii\authclient\AuthAction
'returnUrl' => 'ваш return_url', //https://example.com/auth/auth?authclient=apple,
// должны попасть на AuthController->authAction
'validateAuthState' => false,
'scope' => 'name email',
],
],
],
],
]
namespace frontend\controllers;
use \yii\authclient\AuthAction;
use yii\authclient\ClientInterface;
class AuthController {
public function actions()
{
return [
//сюда обращается пользователь когда хочет авторизоваться, т.е. у вас есть кнопка Sign In With Apple на сайте и сюда ведет
//ссылка с этой кнопки.
//ответ данного экшена - редирект на страницу Apple
//https://example.com/auth/authLink?authclient=apple
'auth-link' => [
'class' => AuthAction::class,
],
//returnUrl из конфига. Сюда Apple переадресует пользователя после авторизации
//Будет POST запрос, и параметры формы будут такими:
//code=123123 - уникальный код, по которому можно достать данные пользователя
//user = {"name":{"firstName":"Имя","lastName":"Фамилия"},"email":"email@email.com"}
//user передается только 1 раз при первой авторизации! в дальнейшем будет только code. По code можно достать email, но не
//имя и фамилию
'auth' => [
'class' => AuthAction::class,
'successCallback' => [$this, 'onAuthSuccess'],
],
];
}
public function onAuthSuccess(ClientInterface $client)
{
$network = $client->getId(); //$network = "apple"
$attributes = $client->getUserAttributes(); //данные пользователя из apple
/*
Вообще-то $attributes - это массив, но я покажу на примере json.
{
"aud": "service_id",
"exp": 1629380175,
"iat": 1629293775,
"iss": "https://appleid.apple.com",
"sub": "1234.asdf.1234", //уникальный ID пользователя в Apple. Лучше varchar(255), т.к. он около 50 символов. Не меняется.
"email": "email@email.com", //email может сменится!
"at_hash": "asdfasdf",
"auth_time": 1629293766,
"email_verified": "true",
"nonce_supported": true,
"first_name": "Имя",
"last_name": "Фамилия",
"post_email": "опять email"
}
*/
//здесь по данным пользователя найти пользователя в базе данных и авторизовать его и вернуть ответ фронтенду
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment