Sample code for 30+ languages & platforms
PHP Extension Requires Chilkat v11.5.0+

Box: Get a Service Account Token with JWT

See more Box Examples

Use the encrypted private key in a Box application configuration file to sign a short-lived assertion and exchange it for an access token. Configure and authorize a JWT Server app first. The enterprise subject obtains the service-account token.

See the Box API guide for setup and the complete workflow.

Chilkat PHP Extension Downloads

PHP Extension
<?php

include("chilkat.php");

$success = false;

//  Requires Chilkat 11.5.0 or later and a previously unlocked Chilkat bundle.
//  See Global Unlock Sample.
//  Guide: Box API Guide.

$success = false;

$config = new CkJsonObject();
$success = $config->LoadFile('qa_data/tokens/box_jwt_config.json');
if ($success != true) {
    print $config->lastErrorText() . "\n";
    exit;
}

$key = new CkPrivateKey();
$success = $key->LoadEncryptedPem($config->stringOf('boxAppSettings.appAuth.privateKey'),$config->stringOf('boxAppSettings.appAuth.passphrase'));
if ($success != true) {
    print $key->lastErrorText() . "\n";
    exit;
}

$header = new CkJsonObject();
$header->UpdateString('alg','RS256');
$header->UpdateString('typ','JWT');
$header->UpdateString('kid',$config->stringOf('boxAppSettings.appAuth.publicKeyID'));
$jwt = new CkJwt();
$prng = new CkPrng();
$nonce = $prng->genRandom(32,'hex');
if ($prng->get_LastMethodSuccess() != true) {
    print $prng->lastErrorText() . "\n";
    exit;
}

$claims = new CkJsonObject();
$claims->UpdateString('iss',$config->stringOf('boxAppSettings.clientID'));
$claims->UpdateString('sub',$config->stringOf('enterpriseID'));
$claims->UpdateString('box_sub_type','enterprise');
$claims->UpdateString('aud','https://api.box.com/oauth2/token');
$claims->UpdateString('jti',$nonce);
$claims->UpdateInt('exp',$jwt->GenNumericDate(45));
$assertion = $jwt->createJwtPk($header->emit(),$claims->emit(),$key);
if ($jwt->get_LastMethodSuccess() != true) {
    print $jwt->lastErrorText() . "\n";
    exit;
}

$curl = new CkHttpCurl();
$curl->SetVar('client_id',$config->stringOf('boxAppSettings.clientID'));
$curl->SetVar('client_secret',$config->stringOf('boxAppSettings.clientSecret'));
$curl->SetVar('assertion',$assertion);
$curl->ClearTargetOutput('*');
$curl->ClearVar('access_token');
$curl->AddTargetOutput('access_token','access_token');
$success = $curl->DoYourThing('curl -X POST \'https://api.box.com/oauth2/token\' --data-urlencode \'grant_type=urn:ietf:params:oauth:grant-type:jwt-bearer\' --data-urlencode \'client_id={{client_id}}\' --data-urlencode \'client_secret={{client_secret}}\' --data-urlencode \'assertion={{assertion}}\'');
if (($success != true) or ($curl->get_StatusCode() != 200)) {
    print 'Box request failed. HTTP status: ' . $curl->get_StatusCode() . "\n";
    print 'Failure reason: ' . $curl->get_FailReason() . "\n";
    exit;
}

if ($curl->VarDefined('!') != true) {
    print 'Expected response fields are missing.' . "\n";
    exit;
}

//  Reuse the token in this HttpCurl instance. JWT tokens are renewed by making
//  a new assertion/token request, not by using a refresh token.
print 'JWT access token obtained.' . "\n";

?>