Войти через Apple: проверить токен на стороне сервера - PullRequest
1 голос
/ 18 июня 2020

Привет, я пытаюсь проверить учетные данные Apple auth, предоставленные клиентским приложением, на стороне сервера я получаю эти поля от клиента: authorizationCode, identityToken вместе с множеством других полей .

Я пробовал читать множество блогов, но ни в одном из них эти поля точно не упоминаются. Каков самый простой способ проверить и получить данные пользователя, используя эти поля для некоторого Apple API

Я сделал это для Google, где клиент передает токен доступа в бэкэнд и с помощью https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=YourToken мы можем проверить токен и получите данные пользователя.

Пожалуйста, предложите аналогичный способ для Apple. Спасибо. Я использую ROR, если это поможет.

Ответы [ 2 ]

2 голосов
/ 20 июня 2020

Наконец, я смог выяснить, как проверить токен доступа, полученный со стороны клиента. Apple не предоставляет API для проверки токена доступа, я настоятельно рекомендую этот блог Он довольно четко объясняет весь процесс. Это ссылка ruby на тот же .

1 голос
/ 24 июня 2020

Для тех, кому для этого нужен клиентский код React-Native, см. Ниже:

import * as React from 'react';
import * as AppleAuthentication from 'expo-apple-authentication';
import { signInWithApple } from '../api';

const AppleAuthenticationButton = () => (
  <AppleAuthentication.AppleAuthenticationButton
    buttonType={AppleAuthentication.AppleAuthenticationButtonType.SIGN_IN}
    buttonStyle={AppleAuthentication.AppleAuthenticationButtonStyle.WHITE}
    cornerRadius={5}
    style={{ width: 200, height: 44 }}
    onPress={async () => {
      try {
        const credential = await AppleAuthentication.signInAsync({
          requestedScopes: [
            AppleAuthentication.AppleAuthenticationScope.FULL_NAME,
            AppleAuthentication.AppleAuthenticationScope.EMAIL,
          ],
        });

        console.log('signed in', credential);
        await signInWithApple(credential);
        // signed in
      } catch (e) {
        if (e.code === 'ERR_CANCELED') {
          console.log('cancelled');
          // handle that the user canceled the sign-in flow
        } else {
          console.log('apple authentication error', e);
          // handle other errors
        }
      }
    }}
  />
);

export default AppleAuthenticationButton;
export const signInWithApple = async (credentials) => {
  const {
    identityToken, user, email, authorizationCode, fullName,
  } = credentials;

  apiCall('users/sign_in', 'post', {
    method: 'apple',
    identityToken,
    user,
    email,
    authorizationCode,
    fullName,
  });
};

Кроме того, как я отметил в своем комментарии ниже, я обнаружил, что в комплекте с яблоком есть 2 ключа. учетные данные и только один из них работает. Понятия не имею, почему, но следующий код работает лучше, чем код, указанный в предыдущем ответе.

  def validate_apple_id

    name = params[:name]
    userIdentity = params[:user]
    jwt = params[:identityToken]

    begin
      header_segment = JSON.parse(Base64.decode64(jwt.split(".").first))
      alg = header_segment["alg"]

      apple_response = Net::HTTP.get(URI.parse(APPLE_PEM_URL))
      apple_certificate = JSON.parse(apple_response)
      token_data = nil

      apple_certificate["keys"].each do | key |
        keyHash = ActiveSupport::HashWithIndifferentAccess.new(key)
        jwk = JWT::JWK.import(keyHash)
        token_data ||= JWT.decode(jwt, jwk.public_key, true, {algorithm: alg})[0] rescue nil
      end

      if token_data&.has_key?("sub") && token_data.has_key?("email") && userIdentity == token_data["sub"]
        yield
      else
        # TODO: Render error to app
      end
    rescue StandardError => e
      # TODO: Render error to app
    end

  end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...