Extract significant parts of an AWS authorization header string

37 Views Asked by At

My input string:

AWS-HMAC-SHA256 Credential=eyJhbGciOiJIUzI1NiIsIngtc3MiOjEy/20160911/cn/user-service/request,SignedHeaders=host;x-aws-date, Signature=d9ee2d43f2067e4b8857f15fa8fff27820051d95a4ec31e93be866f201e0797a

How can I get the values for Credential, SignedHeaders, and Signature?

2

There are 2 best solutions below

0
The fourth bird On BEST ANSWER

Instead of using a regex, you might use explode and array_map:

$str = "AWS-HMAC-SHA256 Credential=eyJhbGciOiJIUzI1NiIsIngtc3MiOjEy/20160911/cn/user-service/request,SignedHeaders=host;x-aws-date, Signature=d9ee2d43f2067e4b8857f15fa8fff27820051d95a4ec31e93be866f201e0797a";
$res = array_map(function($x){
    return explode('=', $x)[1];
}, explode(',', $str));
print_r($res);

Result:

Array
(
    [0] => eyJhbGciOiJIUzI1NiIsIngtc3MiOjEy/20160911/cn/user-service/request
    [1] => host;x-aws-date
    [2] => d9ee2d43f2067e4b8857f15fa8fff27820051d95a4ec31e93be866f201e0797a
)

Demo

0
mickmackusa On

That regularly/predictably formatted string is a "AWS authorization header" or a "AWS Signature Version 4 header".

You can use sscanf(): (Demo)

$str = "AWS-HMAC-SHA256 Credential=eyJhbGciOiJIUzI1NiIsIngtc3MiOjEy/20160911/cn/user-service/request,SignedHeaders=host;x-aws-date, Signature=d9ee2d43f2067e4b8857f15fa8fff27820051d95a4ec31e93be866f201e0797a";
var_export(
    sscanf(
        $str,
        'AWS-HMAC-SHA256 Credential=%[^,],SignedHeaders=%[^,], Signature=%[^,]'
    )
);

There is an alternative syntax whereby you provide the reference variables to populate with the matched values. (Demo)

sscanf(
    $str,
    'AWS-HMAC-SHA256 Credential=%[^,],SignedHeaders=%[^,], Signature=%[^,]',
    $credentials,
    $headers,
    $signature
);

var_dump($credentials, $headers, $signature);

To create an associative array using the exact key and value pairs from the almost-ini-formatted text, use parse_ini_string() after tweaking the format into separate lines. This will be more forgiving of optional spaces around separators or differently ordered components. (Demo)

var_export(
    parse_ini_string(
        preg_replace('/[, ]+/', "\n", $str)
    )
);

Output:

array (
  'Credential' => 'eyJhbGciOiJIUzI1NiIsIngtc3MiOjEy/20160911/cn/user-service/request',
  'SignedHeaders' => 'host',
  'Signature' => 'd9ee2d43f2067e4b8857f15fa8fff27820051d95a4ec31e93be866f201e0797a',
)

Using preg_match_all() is a little too cumbersome with named capture groups; and preg_split() will be a relative chore to ensure key-value relationships.