Как стать автором
Обновить

Добавляем Sign in with Apple на back-end

Время на прочтение2 мин
Количество просмотров11K
На WWDC 2019 Apple представила новую систему авторизации пользователей — Sign in with Apple. Возникла задача интегрировать её в наш back-end и синхронизировать её с уже существующими методами авторизации при помощи email, Google и Facebook. За задачу взялся наш коллега kurenkoff, он и является автором данной статьи. Заинтересовавшихся просим под кат.

Процедура регистрации и авторизации пользователя через Apple



Процедура достаточно примитивная и происходит точно так, как указано на схеме от Apple.

Помимо этого, Apple предоставляет возможность обновления токена:



Схема тоже достаточно простая, есть возможность делать верификацию токена, но мы не используем эту возможность, т.к. у нас нет в этом необходимости.

Реализация авторизации через AppleID


Для реализации авторизации через AppleID мы используем пакет appleLogin. Автором данного пакета допущены некоторые ошибки, но они не являются критическими (а некоторые были совместно исправлены). В первую очередь необходимо инициализировать конфиг при помощи данных полученных через портал разработчика Apple.

config := appleLogin.InitAppleConfig(
    TeamID,         // ID с сайта developer.apple.com, попросить у iOS разработчиков
    ClientID,         // Bundle вашего iOS приложения
    callbackURI,    // ссылка для редиректа при успешной авторизации
    KeyID,            // Сгенерированный ключ с сайта developer.apple.com, попросить у iOS разработчиков
)

privateKey := os.Getenv("PRIVATE_KEY")
err := config.LoadP8CertByByte([]byte(privateKey))
if err != nil {
    return nil, err
}

Затем получить токен:

token, err := config.GetAppleToken(clientToken, tokenExpireTime)
if err != nil {
    return nil, err
}

Важно заметить, какой запрос отправляется на сервера Apple. В документации сказано, что для авторизации необходимо отправить поля client_id, client_secret, code, grant_type, redirect_uri. Все эти поля описаны как обязательные, но redirect_uri можно опустить. Основную сложность представляет client_secret — это JWT, подписанный ключом сгенерированным на портале WWDR:

token := jwt.NewWithClaims(jwt.SigningMethodES256, jwt.MapClaims{
    "iss": a.TeamID,
    "iat": time.Now().Unix(),
    "exp": time.Now().Unix() + expireTime,
    "aud": "https://appleid.apple.com",
    "sub": a.ClientID,
})
token.Header = map[string]interface{}{
    "kid": a.KeyID,
    "alg": "ES256",
}
tokenString, _ := token.SignedString(a.AESCert)

API Apple ответит либо ошибкой, либо вернет структуру. Нас интересуют поле IDToken:

type AppleAuthToken struct {
  AccessToken  string json:"access_token"  //AccessToken
  ExpiresIn    int64  json:"expires_in"    //Expires in
  IDToken      string json:"id_token"      //ID token
  RefreshToken string json:"refresh_token" //RF token
  TokenType    string json:"token_type"    //Token Type
}

IDToken является JWT токеном содержащим данные пользователя:

type AppleUser struct {
    ID            string json:"sub,omitempty"
    Email         string json:"email,omitempty"
    EmailVerified bool   json:"email_verified,string,omitempty"
}

Стоит обратить внимание на то, что email можно получить только при первой авторизации. При попытках повторной авторизации можно получить только ID (уникальный идентификатор пользователя в Sign in with Apple). Для регистрации пользователя нам достаточно этих данных.
Теги:
Хабы:
Всего голосов 9: ↑8 и ↓1+7
Комментарии0

Публикации

Информация

Сайт
www.sports.ru
Дата регистрации
Дата основания
Численность
201–500 человек
Местоположение
Россия

Истории