Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to use jwt Authorization Bearer with rest-client-sdk-bundle ? #8

Open
hvalcourtSerdy opened this issue Feb 20, 2017 · 3 comments
Open

Comments

@hvalcourtSerdy
Copy link

hvalcourtSerdy commented Feb 20, 2017

Hi,

I need to pass some auth information from the Request header to the rest-client-sdk-bundle.

Ex for jwt :
Authorization Bearer eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE0ODc0NjY2MzksIm ...etc...

For now I dont see how to pass the header information I need in the Mapado\RestClientSdk\EntityRepository.

Maybe you have an Idea how I should proceed to pass thoses informations ?

Exemple :
In Mapado\RestClientSdk\EntityRepository code : $data = $this->restClient->get($id); // second parameter not set here

$data = $this->restClient->get($id) call function private function executeRequest($method, $url, $parameters = [])

$this->httpClient->request($method, $url, $parameters);

Thanks for the help

@jdeniau
Copy link
Member

jdeniau commented Feb 21, 2017

The solution we use for now at Mapado is the following:

We have another service that decorates mapado.rest_client_sdk.foo_http_client 👍

        <service id="mapado.rest_client_sdk.decorating_ticketing"                                                                                       
            class="Foo\Bar\DecoratingClient"                                                                               
            decorates="mapado.rest_client_sdk.foo_http_client"                                                                                    
            public="true"                                                                    
        >                                                                                                                                               
            <argument type="service" id="some_service" />                                                                                            
        </service>  

The decorating client looks like this:

<?php                                                                                                                                                   
                                                                                                                                                        
namespace Foo\Bar\Decorator;                                                                                                         
                                                                                                                                                                                                    
use GuzzleHttp\Client;                                                                                                     
use GuzzleHttp\Exception\TransferException;                                                                                                             
use Psr\Http\Message\RequestInterface;                                                                                                                                                       
use Symfony\Component\HttpFoundation\Response;                                                                                                          
                                                                                                                                                        
/**                                                                                                                                                     
 * DecoratoratingClient                                                                                                                                 
 */                                                                                                                                                     
class DecoratingClient implements \GuzzleHttp\ClientInterface                                                                                           
{                                                                                                                                                       
    /**                                                                                                                                                 
     * decorated client                                                                                                                                 
     *                                                                                                                                                  
     * @var Client                                                                                                                                      
     * @access private                                                                                                                                  
     */                                                                                                                                                 
    private $client;                                                                                                                                    
            
    /**
     * some service
     *
     * @var object
     * @access private
     */
    private $someService;

    /** 
     * is token already regenerated
     * @var bool
     * @access private
     */
    private $tokenRegenerated

    /**
     * __construct
     *
     * @param Client $client
     * @param object $someService
     * @access public
     */
    public function __construct(Client $client, object $someService) 
    {
        $this->client = $client;
        $this->someService = $someService;
    }

    /**
     * {@inheritdoc}
     */
    public function send(RequestInterface $request, array $options = [])
    {
        return $this->client->send($request, $options);
    }

    /**
     * {@inheritdoc}
     */
    public function sendAsync(RequestInterface $request, array $options = [])
    {
        return $this->client->sendAsync($request, $options);
    }

    /**
     * {@inheritdoc}
     */
    public function request($method, $uri, array $options = [])
    {
        $token = $this->someService->getTheJwtToken();

        $options['headers'] = array_merge($options['headers'], ['Authorization' => 'Bearer ' . $token]);

        try {
            return $this->client->request($method, $uri, $options);
        } catch (TransferException $e) {
            // regenerate token on 401 errors
            if (!$this->tokenRegenerated) {
                $this->tokenRegenerated = true;
                if ($e->getResponse()->getStatusCode() == Response::HTTP_UNAUTHORIZED) {
                    $token = $this->someService->regenerateToken();
                    $options['headers'] = array_merge(
                        $options['headers'],
                        [ 'Authorization' => 'Bearer ' . $token ]
                    );

                    // resend the same request
                    return $this->client->request($method, $uri, $options);
                }
            }

            throw $e;
        }
    }

    /**
     * {@inheritdoc}
     */
    public function requestAsync($method, $uri, array $options = [])
    {
        return $this->client->requestAsync($method, $uri, $options);
    }

    public function getConfig($option = null)
    {
        return $this->client->getConfig($option);
    }
}

This way, you inject your token on every request you make.

As I'm writing it, I think this is not a very optimal way of doing it but it works. We may provide a setHeaders function on the SDK to provide some default headers.

@hvalcourtSerdy
Copy link
Author

Thanks, I will try this method to deliver in my sprint.

After the sprint, maybe I can help with the setHeaders if you need ?

Merci encore

@jdeniau
Copy link
Member

jdeniau commented Feb 21, 2017

Would love to ! Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants