I can’t get JWT to work with PHP Rest Client.
Here is some source code:
$uri = "https://some-url-to-instance.atlassian.net/rest/api/2/project.json?expand=lead&jwt=$jwt";
$client = new Zend_Http_Client($uri);
// set some parameters
//$client->setAuth($username, $password, Zend_Http_Client::AUTH_BASIC);
// POST request
$client->setMethod(Zend_Http_Client::GET);
$response = $client->request();
$body = $response->getBody();
It always go to Unauthorized (401) page.
Code below prints empty JSON string:
$uri = "https://your-dev-instance.atlassian.net/rest/api/2/project?expand=lead&jwt=".hash_hmac('sha256', $jwt, $hashKey);
//echo $uri;
$client = new Zend_Http_Client($uri);
// set some parameters
//$client->setAuth($username, $password, Zend_Http_Client::AUTH_BASIC);
// POST request
$client->setMethod(Zend_Http_Client::GET);
$response = $client->request();
//echo $response;
$body = $response->getBody();
When I change the & char to different in URL then Unauthorized (401) page not come.
JWT Decoder giving this:
Looks like you’re missing the qsh (see: https://developer.atlassian.com/cloud/jira/platform/understanding-jwt/#a-name-qsh-a-creating-a-query-string-hash)
Can you send over the repo URL of the Jira PHP library you’re using? (there’s a few of them out there)
I have code like this:
$qsh = hash('sha256', "GET&/rest/api/2/project.json&expand=lead");
$iat = (integer) time();
$exp = (integer) time() + 3600;
$token = array(
"iss" => $client,
"iat" => $iat,
"exp" => $exp,
"qsh" => $qsh,
"sub" => $sub
);
$jwt = JWT::encode($token, $secret);
And QHS match with JWT Decoder at: http://jwt-decoder.herokuapp.com/jwt/decode but I still get a 401 Unauhorized page.
With this code below I got everything to work:
$qsh = hash('sha256', "GET&/rest/api/2/project&expand=lead");
$iat = (integer) time();
$exp = (integer) time() * 3600;
$token = array(
"iss" => "com.i4ware.plugin.timesheet.timesheet",
"iat" => $iat,
"exp" => $exp,
"qsh" => $qsh
);
$jwt = JWT::encode($token, $secret);
ISS must be app key.
2 Likes
Hi there
I am trying something similar … Also my first time working on Connect Apps. Here is a sample code I am using. I am running this locally and on my Test server … and both returns a 401.
<?php
require_once('vendor/autoload.php');
use \Firebase\JWT\JWT;
$key = 'test-key-used-in-app-desc';
$iat = (int) time();
$exp = $iat + 3600;
$sec = 'URiDszs6dEQZeTrBRc5H1FwIbdoVnvYmVlgsSIAqduji5NUndVFwvtin0XawuJWa6wLcOoBbUvbinkJCqMTChe';
$method = 'GET';
$baseUrl = 'https://xxx.atlassian.net';
$path = '/rest/api/3/search';
$qs = str_replace('?', '&', '?maxResults=100');
$qshStr = $method.'&'.$path.'&'.substr($qs, 1);
$qsh = hash('sha256', $qshStr);
$claims = array
(
"iss" => $key,
"exp" => $exp,
"iat" => $iat,
"qsh" => $qsh
);
$jwtToken = JWT::encode($claims, $sec);
$apiUrl = $baseUrl.$path.'?jwt='.$jwtToken;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $apiUrl);
curl_setopt($ch, CURLOPT_HTTPGET, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Accept: application/json'));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$curl_response = curl_exec($ch);
echo '<pre>';print_r(json_decode($curl_response, true));echo'</pre>';
curl_close($ch);
Please advise where I am going wrong?
I did everything with Zend Framework 1.12 with its REST Client. Do you want source code?
Thanks for the quick reply, @matti.kiviharju. No worries.
I spent a bit more time playing with this and found the issue … And the exact reason QSH is in place
In my curl request - I only included the jwt query string where as in my qsh. I hash the maxResults item. Hence it was failing the match between the QSH and the actual query being made …
Hope this helps others if at all.
Thanks for offering the assistance again.