feature #30547 [HttpClient] Add new bearer option (dunglas)
This PR was squashed before being merged into the 4.3-dev branch (closes #30547).
Discussion
----------
[HttpClient] Add new bearer option
| Q | A
| ------------- | ---
| Branch? | master
| Bug fix? | no
| New feature? | yes<!-- don't forget to update src/**/CHANGELOG.md files -->
| BC breaks? | no <!-- see https://symfony.com/bc -->
| Deprecations? | no <!-- don't forget to update UPGRADE-*.md and src/**/CHANGELOG.md files -->
| Tests pass? | yes <!-- please add some, will be required by reviewers -->
| Fixed tickets | n/a <!-- #-prefixed issue number(s), if any -->
| License | MIT
| Doc PR | n/a
Add a new "auth_bearer" option to set the corresponding flavor of the `Authorization` header as defined in RFC 6750 and used in OAuth (and others).
Also rename "auth" to "auth_basic" for consistency as discussed with @nicolas-grekas.
Commits
-------
f79ef21458
[HttpClient] Add new bearer option
This commit is contained in:
commit
535c482a4d
@ -71,18 +71,30 @@ trait HttpClientTrait
|
||||
throw new InvalidArgumentException(sprintf('Option "on_progress" must be callable, %s given.', \is_object($onProgress) ? \get_class($onProgress) : \gettype($onProgress)));
|
||||
}
|
||||
|
||||
if (!\is_string($options['auth'] ?? '')) {
|
||||
throw new InvalidArgumentException(sprintf('Option "auth" must be string, %s given.', \gettype($options['auth'])));
|
||||
if (!\is_string($options['auth_basic'] ?? '')) {
|
||||
throw new InvalidArgumentException(sprintf('Option "auth_basic" must be string, %s given.', \gettype($options['auth_basic'])));
|
||||
}
|
||||
|
||||
if (!\is_string($options['auth_bearer'] ?? '')) {
|
||||
throw new InvalidArgumentException(sprintf('Option "auth_bearer" must be string, %s given.', \gettype($options['auth_bearer'])));
|
||||
}
|
||||
|
||||
if (isset($options['auth_basic'], $options['auth_bearer'])) {
|
||||
throw new InvalidArgumentException('Define either the "auth_basic" or the "auth_bearer" option, setting both is not supported.');
|
||||
}
|
||||
|
||||
if (null !== $url) {
|
||||
// Merge auth with headers
|
||||
if (($options['auth'] ?? false) && !($headers['authorization'] ?? false)) {
|
||||
$rawHeaders[] = 'authorization: '.$headers['authorization'][] = 'Basic '.base64_encode($options['auth']);
|
||||
if (($options['auth_basic'] ?? false) && !($headers['authorization'] ?? false)) {
|
||||
$rawHeaders[] = 'authorization: '.$headers['authorization'][] = 'Basic '.base64_encode($options['auth_basic']);
|
||||
}
|
||||
// Merge bearer with headers
|
||||
if (($options['auth_bearer'] ?? false) && !($headers['authorization'] ?? false)) {
|
||||
$rawHeaders[] = 'authorization: '.$headers['authorization'][] = 'Bearer '.$options['auth_bearer'];
|
||||
}
|
||||
|
||||
$options['raw_headers'] = $rawHeaders;
|
||||
unset($options['auth']);
|
||||
unset($options['auth_basic'], $options['auth_bearer']);
|
||||
|
||||
// Parse base URI
|
||||
if (\is_string($options['base_uri'])) {
|
||||
|
@ -34,13 +34,23 @@ class HttpOptions
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuth(string $userinfo)
|
||||
public function setAuthBasic(string $userinfo)
|
||||
{
|
||||
$this->options['auth'] = $userinfo;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
public function setAuthBearer(string $token)
|
||||
{
|
||||
$this->options['bearer'] = $token;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
|
@ -13,6 +13,7 @@ namespace Symfony\Component\HttpClient\Tests;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpClient\HttpClientTrait;
|
||||
use Symfony\Contracts\HttpClient\HttpClientInterface;
|
||||
|
||||
class HttpClientTraitTest extends TestCase
|
||||
{
|
||||
@ -163,4 +164,29 @@ class HttpClientTraitTest extends TestCase
|
||||
yield ['/a/', '/a/b/..'];
|
||||
yield ['/a///b', '/a///b'];
|
||||
}
|
||||
|
||||
public function testAuthBearerOption()
|
||||
{
|
||||
[, $options] = self::prepareRequest('POST', 'http://example.com', ['auth_bearer' => 'foobar'], HttpClientInterface::OPTIONS_DEFAULTS);
|
||||
$this->assertSame('Bearer foobar', $options['headers']['authorization'][0]);
|
||||
$this->assertSame('authorization: Bearer foobar', $options['raw_headers'][0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\HttpClient\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage Option "auth_bearer" must be string, object given.
|
||||
*/
|
||||
public function testInvalidAuthBearerOption()
|
||||
{
|
||||
self::prepareRequest('POST', 'http://example.com', ['auth_bearer' => new \stdClass()], HttpClientInterface::OPTIONS_DEFAULTS);
|
||||
}
|
||||
|
||||
/**
|
||||
* @expectedException \Symfony\Component\HttpClient\Exception\InvalidArgumentException
|
||||
* @expectedExceptionMessage Define either the "auth_basic" or the "auth_bearer" option, setting both is not supported.
|
||||
*/
|
||||
public function testSetBasicAndBearerOption()
|
||||
{
|
||||
self::prepareRequest('POST', 'http://example.com', ['auth_bearer' => 'foo', 'auth_basic' => 'foo:bar'], HttpClientInterface::OPTIONS_DEFAULTS);
|
||||
}
|
||||
}
|
||||
|
@ -26,7 +26,8 @@ use Symfony\Contracts\HttpClient\Test\HttpClientTestCase;
|
||||
interface HttpClientInterface
|
||||
{
|
||||
public const OPTIONS_DEFAULTS = [
|
||||
'auth' => null, // string - a username:password enabling HTTP Basic authentication
|
||||
'auth_basic' => null, // string - a username:password enabling HTTP Basic authentication (RFC 7617)
|
||||
'auth_bearer' => null, // string - a token enabling HTTP Bearer authorization (RFC 6750)
|
||||
'query' => [], // string[] - associative array of query string values to merge with the request's URL
|
||||
'headers' => [], // iterable|string[]|string[][] - headers names provided as keys or as part of values
|
||||
'body' => '', // array|string|resource|\Traversable|\Closure - the callback SHOULD yield a string
|
||||
|
@ -214,7 +214,7 @@ abstract class HttpClientTestCase extends TestCase
|
||||
{
|
||||
$client = $this->getHttpClient();
|
||||
$response = $client->request('POST', 'http://localhost:8057/301', [
|
||||
'auth' => 'foo:bar',
|
||||
'auth_basic' => 'foo:bar',
|
||||
'body' => function () {
|
||||
yield 'foo=bar';
|
||||
},
|
||||
@ -291,7 +291,7 @@ abstract class HttpClientTestCase extends TestCase
|
||||
$client = $this->getHttpClient();
|
||||
$response = $client->request('GET', 'http://localhost:8057/301', [
|
||||
'max_redirects' => 1,
|
||||
'auth' => 'foo:bar',
|
||||
'auth_basic' => 'foo:bar',
|
||||
]);
|
||||
|
||||
try {
|
||||
|
Reference in New Issue
Block a user