Closed pbowyer closed 1 year ago
Hi @pbowyer, thanks for the suggestion, I think it's a great idea. Are you able to add the field name mapping support and send a PR?
Thanks for the feedback @kamermans. Yes I'll get a PR created in the next couple of weeks.
@pbowyer what do you think about trying to guess the field name, so access_token
and accessToken
are both matched? This could be done, for example, by removing all characters except letters and numbers, then doing a case-insensitive match against accesstoken
.
Hi @pbowyer, it occurred to me that you can also do what you want by creating a different RawTokenFactory
like this:
class MyTokenFactory extends \kamermans\OAuth2\Token\RawTokenFactory
{
public function __invoke(array $data, RawToken $previousToken = null)
{
$mappings => [
"access_token" => 'accessToken',
"expires_in" => 'expiresIn',
]
foreach ($mappings as $new_key => $old_key) {
if (!array_key_exists($old_key, $data)) {
continue;
}
$data[$new_key] = $data[$old_key];
}
return parent::__invoke($data, $previousToken);
}
}
Then you can use it like this:
$oauth = new OAuth2Middleware($grant_type);
$oauth->setTokenFactory(new MyTokenFactory);
Token factories don't have to implement any interface, but they do need to be callable and return an object that implements kamermans\OAuth2\Token\TokenInterface
.
You can even do the implementation in a closure if you prefer:
$oauth = new OAuth2Middleware($grant_type);
$default_factory = new \kamermans\OAuth2\Token\RawTokenFactory();
$mappings => [
"access_token" => 'accessToken',
"expires_in" => 'expiresIn',
];
$oauth->setTokenFactory(function (array $data, RawToken $previousToken = null) use ($default_factory, $mappings) {
foreach ($mappings as $new_key => $old_key) {
if (!array_key_exists($old_key, $data)) {
continue;
}
$data[$new_key] = $data[$old_key];
}
return $default_factory($data, $previousToken);
});
If you do still want to add a mapping feature, I'm happy to merge it, but I think it would be best to do the mapping on the TokenFactory instead of each of the grant type objects, or perhaps to create a base grant type class and inherit the mapping functionality from there.
Thanks for this library, it's been really easy to integrate with!
I've used it to authenticate with Salesforce Marketing Cloud's REST API. The only complication was that the field names returned by the authentication endpoint are different from those
guzzle-oauth2-subscriber
expects (accessToken
vsaccess_token
,expiresIn
vsexpires_in
) so I had to subclassClientCredentials
to modify the returned data:The request field names can be configured when setting up the middleware, without any need for subclassing:
Would you consider adding mapping to the
ClientCredentials
class, as HWIOAuthBundle does with paths? An example is: