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
Related
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 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
I'm trying to make 2 api calls at the same time, the first gets a token and the second brings the user data.
The problem is that when i pass the token on the second api call it gives me a session expired.
$client = new Client([
'base_uri' => 'https://portaldoagente.com.br/WCF/wcfTravellink/Loja.svc/',
'headers' => [
'Content-Type' => 'application/json'
]
]);
First call:
$response = $client->post('Autenticar',
['body' => json_encode(
[
'login' => 'example',
'senha' => 'example'
]
)],
);
$body = $response->getBody()->getContents();
$responseXml = simplexml_load_string($body);
$token = $responseXml->children;
$response = $client->post('ConsultarCliente',
['body' => json_encode(
[
'token'=> $token,
'ClienteLogin' => [
'Login' => 'example',
'Senha' => 'example'
]
]
)]
);
$Consulta = $response->getBody()->getContents();
The token needed to stay in the session so it would not expire?
When I try this in postman it works fine, first I make a call to the first method to get the token, then I make another call to the second method passing the token.
Using Laravel 5 and trying to send some data from my site to another one, which provides me with the REST API. But they use cookies as a authorization. For this moment, I've passed auth successfully. And stuck on how should I send this cookie to API interface via POST method? Here is my listing.
Thanx in advance.
P.S. All things are going on inside the controller.
if (Cookie::get('amoauth') !== null) {
//COOKIE IS HERE
$client = new Client();
$newlead = $client->post('https://domain.amocrm.ru/private/api/v2/json/leads/set', [
'add' => [
'add/name' => 'TEST LEAD',
'add/date_create' => time(),
'add/last_modified' => time(),
'add/status_id' => '1',
'add/price' => 5000
]
]);
} else {
$client = new Client();
$auth = $client->post('https://domain.amocrm.ru/private/api/auth.php',[
'USER_LOGIN' => 'login',
'USER_HASH' => 'hash',
'type' => 'json'
]);
$auth = $auth->getHeaders('Set-Cookie');
Cookie::queue('amoauth', $auth, 15);
return redirect('/test');
}
Now it returns me the following:
Client error: `POST https://domain.amocrm.ru/private/api/v2/json/leads/set` resulted in a `401 Unauthorized` response.
Found the solution: switched to ixudra/curl.
Trying to wrap my head around using Laravel's Passport with mobile clients. The Password Grant type of authentication seems to be the way to go, and i have it working with my iOS app, however i can't get token refreshing to work.
When authenticating i get a token and a refresh token which i store, however when the token expires, calling the oauth/token/refresh route doesn't work. The route is using the web middleware which means my app using the api route can't access it. I'm not sure if they intended for mobile clients to never refresh or if they wanted you to roll your own refreshing? If anyone has insight on how this is supposed to work, that'd be great.
The oauth/token/refresh route is not for refreshing access tokens. It is used to refresh transient tokens, which are used when you consume your own API from your javascript.
To use your refresh_token to refresh your access token, you need to call the oauth/token route with the grant_type of refresh_token.
This is the example provided by the documentation:
$http = new GuzzleHttp\Client;
$response = $http->post('http://your-app.com/oauth/token', [
'form_params' => [
'grant_type' => 'refresh_token',
'refresh_token' => 'the-refresh-token',
'client_id' => 'client-id',
'client_secret' => 'client-secret',
'scope' => '',
],
]);
return json_decode((string) $response->getBody(), true);
One note about scopes, when you refresh the token, you can only obtain identical or narrower scopes than the original access token. If you attempt to get a scope that was not provided by the original access token, you will get an error.
I've done something like.
Created an endpoint for grant refresh token.
and in my controller,
public function userRefreshToken(Request $request)
{
$client = DB::table('oauth_clients')
->where('password_client', true)
->first();
$data = [
'grant_type' => 'refresh_token',
'refresh_token' => $request->refresh_token,
'client_id' => $client->id,
'client_secret' => $client->secret,
'scope' => ''
];
$request = Request::create('/oauth/token', 'POST', $data);
$content = json_decode(app()->handle($request)->getContent());
return response()->json([
'error' => false,
'data' => [
'meta' => [
'token' => $content->access_token,
'refresh_token' => $content->refresh_token,
'type' => 'Bearer'
]
]
], Response::HTTP_OK);
}