Я пытаюсь создать токен доступа, используя идентификатор пользователя приложения box. Я использовал следующий код для создания пользователя приложения коробки
curl https://api.box.com/2.0/users \
-H "Authorization: Bearer <TOKEN>" \
-d '{"name": "Ned Stark", "is_platform_access_only": true}' \
-X POST
Тогда это даст следующий результат
{"type":"user","id":"2199107004","name":"Ned Stark","login":"[email protected]","created_at":"2017-08-03T00:58:04-07:00"
Можно ли сгенерировать токен доступа, используя идентификатор пользователя приложения box?
отредактированный
Я сгенерировал открытый ключ в BOX API. Тогда у меня есть файл, который имеет открытый ключ и частный ключ, как показано ниже,
{
"boxAppSettings": {
"clientID": <Client ID>,
"clientSecret": <clientsecret>,
"appAuth": {
"publicKeyID": <publickeyid>,
"privateKey": "-----BEGIN ENCRYPTED PRIVATE KEY-----\Key heresn-----END ENCRYPTED PRIVATE KEY-----\n",
"passphrase": <phrase>
}
},
"enterpriseID": <enterpriseId>
}
Затем я сгенерирую заголовок и полезную нагрузку, как это следует
$header = ["typ"=> "JWT", "alg"=>"RS256","kid"=> <public key id>];
$payload = [
"iss"=> "<client id>",
"sub"=> "<APP USER ID>",
"box_sub_type"=> "user",
"aud"=>"https://api.box.com/oauth2/token",
"jti"=>"<I don't know what is this>",
"exp"=>1428699385
];
$header = base64_encode(json_encode($header));
$payload = base64_encode(json_encode($payload));
После этого я застрял, как реализовать здесь закрытый и открытый ключ. На самом деле у меня есть файл JSON, который загружается из BOX API.
И я не могу понять, что такое JTI
? Как добавить в этот файл JSON открытый ключ и | или закрытый ключ? Как это сделать?
И я должен сгенерировать закрытый ключ вручную в соответствии с документом, как следует
openssl genrsa -aes256 -out private_key.pem 2048
Тогда я дал пароль как «12345». И сгенерируйте открытый ключ следующим образом:
openssl rsa -pubout -in private_key.pem -out public_key.pem
Затем я добавил открытый ключ в BOX-API и сделал следующий код:
$data = file_get_contents('private_key.pem');
$result = openssl_pkey_get_private($data,"12345");
print_r($result);
Это дает следующий результат
Resource id #4
Это не похоже на зашифрованные данные. А как реализовать private и public при вызове box api в php.?
Я не буду рекомендовать вам реализовать это самостоятельно, поскольку уже есть несколько библиотек, реализующих этот протокол. Однако я разделю свой ответ на 2 части: первая часть объясняет, как использовать пакет с открытым исходным кодом для решения вашей проблемы, вторая часть помогает вам, если вы хотите подписать закрытые ключи.
Есть несколько пакетов php, которые поддерживают подпись JWT, на момент написания наиболее часто используемый lcobucci / JWT, но есть и другие реализации, найденные здесь:
https://packagist.org/search/?q=jwt
Ты можешь использовать композитор установить его. Поскольку версия 4.0 не документирована прямо сейчас, я предлагаю вам установить 3.2 и взглянуть на ПРОЧТИ МЕНЯ файл этой версии.
Вы можете потребовать это в вашем проекте, используя: composer require lcobucci/jwt:^3.2
Ваш пример кода показывает, что вам нужен RSA256, в библиотеке есть пример для этого:
<?php
use Lcobucci\JWT\Builder;
use Lcobucci\JWT\Signer\Keychain; // just to make our life simpler
use Lcobucci\JWT\Signer\Rsa\Sha256; // you can use Lcobucci\JWT\Signer\Ecdsa\Sha256 if you're using ECDSA keys
$signer = new Sha256();
$keychain = new Keychain();
$token = (new Builder())
->setIssuer('http://example.com') // Configures the issuer (iss claim)
->setAudience('http://example.org') // Configures the audience (aud claim)
->setId('4f1g23a12aa', true) // Configures the id (jti claim), replicating as a header item
->setIssuedAt(time()) // Configures the time that the token was issue (iat claim)
->setNotBefore(time() + 60) // Configures the time that the token can be used (nbf claim)
->setExpiration(time() + 3600) // Configures the expiration time of the token (nbf claim)
->set('uid', 1) // Configures a new claim, called "uid"->sign($signer, $keychain->getPrivateKey('file://{path to your private key}')) // creates a signature using your private key
->getToken(); // Retrieves the generated token
При использовании открытых и закрытых ключей вы всегда должны быть уверены в безопасности своего закрытого ключа. Однако вы можете легко опубликовать свой открытый ключ в мире, не ставя под угрозу безопасность.
Подписание осуществляется с помощью закрытого ключа, поскольку вы не хотите, чтобы люди могли подделывать вашу подпись, подпись с открытой частью позволит каждому сделать это. Это также означает, что шаг проверки всегда использует открытый ключ, потому что каждый должен иметь возможность это сделать.
Приведенный вами пример кода просто загружает закрытый ключ, но не выполняет с ним никаких действий. Для подписи вам необходимо использовать openssl_sign
с вашей переменной. Resource #xx
просто означает ссылку на что-то внешнее в php.
<?php
// Data to sign
$payload = 'TEST';
// Generate a new key, load with: openssl_pkey_get_private
$privateKey = openssl_pkey_new(array('private_key_bits' => 512)); // NOT SECURE BUT FAST
// Extract public part from private key
$details = openssl_pkey_get_details($privateKey);
// Use openssl_pkey_get_public to load from file
$publicKey = $details['key'];
// Generated by openssl_sign
$signature = null;
// Sign with private key
openssl_sign($payload, $signature, $privateKey, OPENSSL_ALGO_SHA256);
// Use base64 because the signature contains binairy data
echo 'Signed data: '.base64_encode($signature).PHP_EOL;
// Use publicKey to verify signature
$valid = openssl_verify($payload, $signature, $publicKey, OPENSSL_ALGO_SHA256);
echo 'Signature is '.($valid ? 'Valid' : 'Invalid').PHP_EOL;
Если вы все еще хотите реализовать полный протокол, я предлагаю вам еще раз взглянуть на пакет. И как уже предложено в комментариях полная спецификация:
https://www.rfc-editor.org/rfc/rfc7519.txt
Последний совет: JWT использует несколько других символов для base64, чем php, поэтому убедитесь, что обрабатываете это правильно.
Других решений пока нет …