【问题标题】:How to create the access token using app user id in Box-API?如何使用 Box-API 中的应用用户 ID 创建访问令牌?
【发布时间】:2018-01-10 16:55:20
【问题描述】:

我正在尝试使用盒子应用用户 ID 创建访问令牌。我已经使用以下代码来创建盒子应用用户

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":"AppUser_399382_9BNZHI03nJ@boxdevedition.com","created_at":"2017-08-03T00:58:04-07:00"

是否可以使用盒子应用用户ID生成访问令牌?

已编辑

我已经在 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和payload,如下

$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));

在此之后,我被困在如何在这里实现私钥和公钥。实际上我有从 BOX API 下载的 JSON 文件。 我不明白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

这些看起来不像加密数据。以及在php中调用box api时如何实现private和public?

【问题讨论】:

  • 好吧,您需要了解 OAuth 的一般工作原理,尤其是 OAuth 2.0:oauth.net/2。或者只是请人做这项工作。
  • 看来你需要一个 JWT 令牌。在这里查看一些文档jwt.io/introduction
  • @lauda 我了解标头和有效负载,但我不了解如何添加/使用私钥?
  • @lauda 我不了解签名。?如何使用私钥创建签名?
  • 有关 JWT 的更多信息,您应该阅读 RFC 文档rfc-editor.org/rfc/rfc7519.txt

标签: php rest access-token box-api box


【解决方案1】:

我不建议你自己实现这个,因为已经有几个库实现了这个协议。但是,我将答案分为两部分,第一部分解释了如何使用开源包来解决您的问题,第二部分可以帮助您解决是否要进行私钥签名。

使用包

有几个支持 JWT 签名的 php 包,目前使用最多的是 lcobucci/jwt,但这里也有其他实现: https://packagist.org/search/?q=jwt

您可以使用composer 来安装它。由于现在没有记录 4.0 版,我建议您安装 3.2 并查看该版本的 README 文件。

您可以在您的项目中使用: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

签名和验证

在使用公钥和私钥时,您必须始终确保您的私钥安全。但是,您可以轻松地向全世界发布您的公钥,而不会影响安全性。

使用私钥进行签名,因为您不希望人们能够伪造您的签名,所以使用公共部分进行签名将使每个人都可以这样做。这也意味着验证步骤始终使用公钥,因为每个人都应该能够做到。

用 PHP 实现

您提供的代码示例只是加载了一个私钥,但没有对其进行任何操作。为了签名,您需要将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;

还有什么

如果你还想实现完整的协议,我建议你再看一下这个包。正如 cmets 已经建议的那样,完整的规范:

https://www.rfc-editor.org/rfc/rfc7519.txt

最后提示:JWT 对 base64 使用的字符与 php 不同,因此请务必正确处理。

【讨论】:

    猜你喜欢
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2011-04-02
    • 1970-01-01
    • 2019-08-28
    • 2014-11-07
    • 2021-05-02
    • 2014-09-13
    相关资源
    最近更新 更多