Ошибка 401 при межсерверной аутентификации CloudKit на Node JS

Я пытаюсь запросить общедоступную базу данных CloudKit, используя межсерверную аутентификацию. Я сгенерировал ключ в соответствии с документами Apple, но независимо от того, что я делаю, я получаю эту ошибку:

401 - Unauthorized

data: {
  uuid: '...',
  serverErrorCode: 'AUTHENTICATION_FAILED',
  reason: 'no auth method found'
}

Насколько я могу судить, я все настроил согласно документам, но очевидно, что я делаю что-то не так. Вот что у меня есть в моем приложении Node:


let date = moment().format('YYYY-MM-DD[T]HH:mm:ss[Z]')
let domain = 'https://api.apple-cloudkit.com'
let subpath = '/database/1/iCloud.<my container>/development/public/users/current'

let key = fs.readFileSync(__dirname +'/../eckey.pem', 'utf8')
let keyID = 'abc123...'

let requestBody = ''
let bodyHash = crypto.createHash('SHA256').update(requestBody).digest('base64')

let message = date+':'+bodyHash+':'+subpath

let signature = crypto.createSign('RSA-SHA256').update(message).sign(key, 'base64')

let headers = {
  'X-Apple-CloudKit-Request-KeyID': keyID,
  'X-Apple-CloudKit-Request-ISO8601Date': date,
  'X-Apple-CloudKit-Request-SignatureV1': signature
}

try{
  await axios.post(domain+subpath, requestBody, { headers: headers })
  console.log('--- :) ---')
}catch(error){
  console.log('=== :( ===')
  console.log(error)
}

Я уже просмотрел этот полезный пост SO, но я все еще застрял.

Может ли кто-нибудь увидеть, что я могу делать неправильно?


person Clifton Labrum    schedule 16.05.2020    source источник


Ответы (1)


Мне пришлось сделать массу устранения неполадок, чтобы понять это, но ради потомков, вот что я сделал не так:

=== Исправление № 1 ===

Моя дата генерировала местное время, которое было неточным, потому что формат подразумевает время Zulu/UTC (из-за Z).

Исправление заключалось в добавлении .utc() к моменту:

let date = moment().utc().format('YYYY-MM-DD[T]HH:mm:ss[Z]')

=== Исправление № 2 ===

Очевидно, Axios не понравилось, как я форматировал запрос. Изменение его на это (с отдельными baseURL и url) работает:

let response = await axios({ 
  method: 'post', 
  baseURL: baseURL, 
  url: '/records/modify', 
  data: query, 
  headers: headers 
})

Кажется, теперь все отлично работает с этими исправлениями.

person Clifton Labrum    schedule 17.05.2020