I am trying to generate JWT token for apple connect API (to get sales report) in php.
i tried this format (using firebase/php-jwt)
$Private_key = file_get_contents('AuthKey_XYZ.p8');
$Issuer_ID = 'XYZ';
$Key_ID = 'ZDJ';
$data = [
'iss' => $Issuer_ID,
'iat' => \Carbon\Carbon::now()->timestamp,
'exp' => \Carbon\Carbon::now()->addMinutes(20)->timestamp,
'aud' => "appstoreconnect-v1"
];
$jwt = JWT::encode($data, $Private_key,'HS256', $Key_ID);
And receiving 401, did i missed something or the format is
I'm pretty sure the JWT encryption algorithm you are specifying is wrong. Try setting it to 'ES256', e.g:
$jwt = JWT::encode($data, $Private_key,'ES256', $Key_ID);
from the docs under "Create the JWT header"
https://developer.apple.com/documentation/appstoreconnectapi/generating_tokens_for_api_requests
Related
I try to create a restful api with JWT in CI4, when I create token with code below :
$key = getenv('TOKEN_SECRET');
$payload = array(
"iat" => 1356999524,
"nbf" => 1357000000,
"uid" => $user['id'],
"email" => $user['email']
);
$token = JWT::encode($payload, $key);
Why do I get the error:
Expected 3 arguments. Found 2
The third paramter should be the algorithm you are trying to use for encoding.
For Example, HS256 is one of the algorithms.
So in your example it will be :
$token = JWT::encode($payload, $key, 'HS256');
You can refer to the following link for reference:
https://packagist.org/packages/firebase/php-jwt
I have been having similar difficulties to this question. I need to create a JWT in php. I have the following code:
define('RSA_PRIVATE', 'MIICXAIB......EWxOf9o=');
$payload = json_encode([
'sub' => 'username',
'email' => 'john#example.com',
'given_name' => 'John',
'family_name' => 'Example',
'iat' => time(),
'nonce' => '12345'
]);
$header = json_encode([
'typ' => 'JWT',
'alg' => 'RS256'
]);
$base64UrlHeader = base64UrlEncode($header);
$base64UrlPayload = base64UrlEncode($payload);
$signature = hash_hmac('sha256', "$base64UrlHeader.$base64UrlPayload", RSA_PRIVATE, true);
$base64UrlSignature = base64UrlEncode($signature);
$jwt = "$base64UrlHeader.$base64UrlPayload.$base64UrlSignature";
echo($jwt);
function base64UrlEncode($text)
{
return str_replace(
['+', '/', '='],
['-', '_', ''],
base64_encode($text)
);
}
Whenever I attempt to validate with the third party that needs my JWT it comes back with a message telling me
Signature validation failed: rsa signature did not match
When I attempt to validate using the JWT debugger, it too says it is invalid.
Am I missing something here? Like the previous question I have only ever seen examples where people are using small secrets and not private RSA keys.
Following the answer by #Michal Trojanowski I went on to use openssl_sign. However this did not work when I had the key as a variable in my code. Instead, following the example on the php manual I managed to get it to work using the following adjustment:
$private_key = openssl_pkey_get_private("file:///path.to/jwtRS256.key");
openssl_sign(
"$base64UrlHeader.$base64UrlPayload",
$signature,
$private_key,
"sha256WithRSAEncryption"
);
openssl_free_key($private_key);
$base64UrlSignature = zd_base64UrlEncode($signature);
$jwt = "$base64UrlHeader.$base64UrlPayload.$base64UrlSignature";
You chose RS256 as the signature algorithm, which is an asymmetrical signing algorithm and you create the signature with a HMAC function, which is a symmetrical signing algorithm.
If you want to stick to RS256 try to follow this answer: https://stackoverflow.com/a/43313973/1712294
If you want to stick with a symmetrical algorithm change the data in your header to
$header = json_encode([
'typ' => 'JWT',
'alg' => 'HS256'
]);
The recommended way is to go with an asymmetrical algorithm.
I'm trying to get the access token using the Docusign JWT authentication, but I always get:
{"error":"invalid_grant","error_description":"unsupported_grant_type"}
I double checked all the data (integration key, api username, etc) and they are fine.
I followed all the steps in the Docusign guidelines.
The only part I'm not 100% sure is when I generate the signature of the JWT token.
The documentation says:
The first two parts of the JWT are signed with your application's private key (using the RSA SHA-256 digital signature algorithm) as shown in the diagram.
This is how I'm generating the signature:
$header = [
'typ' => 'JWT',
'alg' => 'RS256'
];
$body = [
'iss' => getenv('INTEGRATION_KEY'),
'sub' => getenv('API_USERNAME'),
'iat' => time(),
'exp' => time() + 3600,
'aud' => str_replace('https://', '', getenv('AUTH_URL')),
'scope' => 'signature impersonation'
];
$signature = JWT::encode($body, file_get_contents(env('PRIVATE_KEY')), 'RS256');
$header = $this->base64url_encode(json_encode($header));
$body = $this->base64url_encode(json_encode($body));
$jwt = $header . '.' . $body . '.' . $signature;
Is that correct?
If not, and since JWT::encode expects an array as first parameter, how should I do to make it work?
This is how I'm requesting the access token:
return Http::withHeaders(
[
'Content-Type' => 'application/x-www-form-urlencoded'
]
)->post(
getenv('AUTH_URL') . '/oauth/token',
[
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt
]
);
Thanks!
Apparently Firebase JWT encode method doesn't encode a string in the right way.
I used this:
$header = $this->base64url_encode(json_encode($header));
$body = $this->base64url_encode(json_encode($body));
openssl_sign(
$header.".".$body,
$signature,
file_get_contents(env('PRIVATE_KEY_PATH')),
"sha256WithRSAEncryption"
);
and it worked.
Make sure you're using the same scopes when requesting consent and requesting the jwt token.
Thanks everyone for the help.
Creating a correct JWT token is hard. I suggest you either use the requestJWTUserToken from the PHP SDK or review its source to see how it makes the OAuth request.
I was having the same problem in a application using Laravel 6 and I managed to solve it as follows:
// the Header will not be needed as it is automatically generated
$header = [
'typ' => 'JWT',
'alg' => 'RS256'
];
$body = [
'iss' => getenv('INTEGRATION_KEY'),
'sub' => getenv('API_USERNAME'),
'iat' => time(),
'exp' => time() + 3600,
'aud' => str_replace('https://', '', getenv('AUTH_URL')),
'scope' =>'signature impersonation'
];
/**
* Note that when creating the JWT, only the $body is provided,
* as the function already performs the necessary concatenations.
* in your code you put it like this:
* $jwt = $header . '.' . $body . '.' . $signature;
* which generates a hash that cannot be validated,
*/
// create the JWT
$jwt = JWT::encode($body , $privateKey, 'RS256');
// make the request
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', getenv('AUTH_URL').'/oauth/token',['query' =>[
'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
'assertion' => $jwt,
]
]);
echo '<pre>';
print_r($response);
echo '</pre>';
I have to implement bigcommerce API integration with PHP
and I am trying to use the official library from https://github.com/bigcommerce/bigcommerce-api-php
and I am not even able to start step 1 here.
Issues:
Basic Auth method
Bigcommerce::configure(array(
'store_url' => 'https://store.mybigcommerce.com',
'username' => 'admin',
'api_key' => 'd81aada4xc34xx3e18f0xxxx7f36ca'
));
So the question here is how to get a username? bigcommerece user only created using email address so how to get username here?
OAuth method
In order to obtain the auth_token you would consume Bigcommerce::getAuthToken method
$object = new \stdClass();
$object->client_id = 'xxxxxx';
$object->client_secret = 'xxxxx;
$object->redirect_uri = 'https://app.com/redirect';
$object->code = $request->get('code');
$object->context = $request->get('context');
$object->scope = $request->get('scope');
$authTokenResponse = Bigcommerce::getAuthToken($object);
Bigcommerce::configure(array(
'client_id' => 'xxxxxxxx',
'auth_token' => $authTokenResponse->access_token,
'store_hash' => 'xxxxxxx'
));
here the question is what is the $request variable? also, redirect_uri is the bigcommerce store URL or my site URL?
Please can anyone help to get started with this?
It's because that library is a bit out of date with how api accounts are managed. For the basic auth you would use "legacy accounts". You can just use the OAuth method without the oAuth flow (assuming you're trying to connect to your own store, not create an app).
Just the following will work:
Bigcommerce::configure(array(
'client_id' => 'client-id',
'auth_token' => 'access-token',
'store_hash' => 'store-hash'
));
You should get these after creating a user in the dashboard (you can ignore the secret for this use case)
I am facing a problem to decode token (JWT). Here it's encoded successfully and it provides me with a token. My code code is:
$tokenData = $this->set([
'data' => [
'token' => JWT::encode([
'sub' => $user['username'],
'exp' => time() + 202200
],
Security::salt())
],
'_serialize' => ['success', 'data']
]);
It returns "token":{"token":"xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"}
To decode this I used:
$JWT_KEY = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$token = JWT::decode($JWT_KEY);
dd($token);
How can I get it? specially time. Thanks in advance
if you are using firebase JWT take a look to: https://github.com/firebase/php-jwt
for me that command worked, here's a piece of my code:
$jwt= $this->request->data['_token'];
$decoded = JWT::decode($jwt, $this->pepper, array('HS256'));
//$decoded is an object with your token decoded data