JWT App validation via cURL (PHP) results in 401

I am trying to create an application for Jira Service Desk, however, I keep getting stuck at the following point:
After successfully generating a valid JWT, I try to access the rest URL via cURL, but I keep getting 401, unauthorized:

This is the function where I call the JWT-creature function:

public function generateJWT() {
    $j = new JWTModel();
    $o = new ObjectModel();
    $r = new RestModel();

    $object = $o->getClientByUrl('https://<my-instance-for-demo>.atlassian.net');
    $jwt = $j->generate(10000, $object->key, $object->clientKey, $object->sharedSecret);
    
    print_r($r->issueData($jwt, 10000));
}

This is the function that creates the JWT:

public function generate($issue, $key, $clientKey, $sharedSecret) {
    $token = [
        "iss" => $key,
        "iat" => time(),
        "exp" => time() * 3600,
        "sub" => $clientKey,
        "qsh" => hash('sha256', "GET&/rest/api/latest/issue/" . $issue)
    ];

    $jwt = JWT::encode($token, $sharedSecret);
    return $jwt;
}

And eventually the cURL-function:

public function issueData($jwt, $issue) {
    try {
        $curl = new Curl();
        $curl->setOpt(CURLOPT_SSL_VERIFYPEER, false);
        $curl->setOpt(CURLOPT_POST, false);
        $curl->setOpt(CURLOPT_HTTPHEADER, ['Authorization: JWT ' . $jwt, 'Content-type: application/json']);
        $curl->post("https://<my-instance-for-demo>.atlassian.net/rest/api/latest/issue/" . $issue);

        return $curl->response;
     } catch (\ErrorException $e) {
        return $e->getMessage();
     }
}

This is my connect:

{
  "name": "XXXX XXX",
  "description": "XXX makes your life easier",
  "key": "xxxx-app",
  "baseUrl": "https://xxx.xxxx.nl",
  "vendor": {
    "name": "xxxx",
    "url": "http://xxx.nl"
  },
  "links": {
    "self": "https://xxx.xxx.nl/atlassian-connect.json",
    "homepage": "https://xxx.nl/"
  },
  "authentication": {
    "type": "jwt"
  },
  "lifecycle": {
    "installed": "/installed",
    "uninstalled": "/unstalled"
  },
  "scopes": [
    "READ", "WRITE"
  ],
  "apiVersion": 1,
  "modules": {
    "webPanels": [{
      "conditions": [{
        "condition": "user_is_logged_in"
      }],
      "key": "xxx-xxx-insert",
      "name": {
        "value": "xxx"
      },
      "url": "/canned?project={servicedesk.serviceDeskId}&issueId={issue.id}&issueKey={issue.key}",
      "location": "atl.jira.view.issue.left.context",
      "layout": {
        "width": "100%",
        "height": "100px"
      },
      "weight": 999
    }]
  }
}

Does anyone sees the point where I made a mistake?

My first suggestion would be to check if the query string hash you generate is accurate. You can do so by using this tool: JWT Decoder. The hash for GET&/rest/api/latest/issue/10000& is 3a6df96de7b7c61eee6397e50530d7f4828fc3fcdd7727292e98e1b1016d0ecf.

Once you’ve verified that this works, try making the request in Postman to see if the request itself (with the generated JWT) is valid. This will allow you to identify if the issue is with the request or with your cUrl code.

Hi Willem-Jelle,

Try using $curl->get() instead of $curl->post(). All the other code you wrote is good tho.

1 Like

He Remie,

Thanks for your message! When testing, my JWT and type of connection was good all the time. The only thing I forgot, was changing the curl post to the curl get.

Such mistakes :face_with_thermometer::weary:

1 Like

:joy: haha, well that is definitely something you can easily overlook

I posted an update here as well Solved: JWT App validation via cURL (PHP) results in 401

But I noticed that expiry time should be time + 3600 - correct?

Also I am wondering if you can help me? I posted an update here too I can't get JWT to work with PHP Rest Client - #6 by YatishMadhav - please have a look and let me know if there is something I am doing incorrectly?

Thank you in advance.