Passport: client_credentials API always return Missing "Authorization" header

Created on 17 Mar 2017  ·  7Comments  ·  Source: laravel/passport

Hi,
I set up an API for iOS APP to connect. But when I use client_credentials as middware and tested on my browser with url: http://localhost/getToken, I was always got error:

[message] => The resource owner or authorization server denied the request. 
[hint] => Missing "Authorization" header

I using laravel 5.4 and below is my project file that I've been set up.
My Kernel.php file:

protected $middlewareGroups = [
        'web' => [
            \App\Http\Middleware\EncryptCookies::class,
            \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
            \Illuminate\Session\Middleware\StartSession::class,
            \Illuminate\View\Middleware\ShareErrorsFromSession::class,
            \App\Http\Middleware\VerifyCsrfToken::class,
            \Illuminate\Routing\Middleware\SubstituteBindings::class,
           // \Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
        ],
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

/**
 * The application's route middleware.
 *
 * These middleware may be assigned to groups or used individually.
 *
 * @var array
 */
protected $routeMiddleware = [
    //'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth' => \App\Http\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
    'scopes' => \Laravel\Passport\Http\Middleware\CheckScopes::class,
    'scope' => \Laravel\Passport\Http\Middleware\CheckForAnyScope::class,
    //'client_credentials' => \Laravel\Passport\Http\Middleware\CheckClientCredentials::class,
    'client_credentials' => \App\Http\Middleware\CheckClientCredentials::class,
];

My configauth.php file:

`'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],
        'api' => [
            'driver' => 'passport',
            'provider' => 'users',
        ],
        'admin' => [
            'driver' => 'session',
            'provider' => 'admin',
        ],
    ],`

My AppProvidersAuthServiceProvider file:

public function boot()
    {
        $this->registerPolicies();
        Passport::routes();
        Passport::tokensExpireIn(Carbon::now()->addDays(15));
        Passport::refreshTokensExpireIn(Carbon::now()->addDays(30));
        //Passport::enableImplicitGrant();
        Passport::tokensCan([
            'users' => 'Action with users',
            'bds' => 'Action with bds',
        ]);
        //
    }

My route: web,php

Route::middleware('client_credentials')->get('/test', function () {
    return response()->json([ 'status' => 'ok' ], 200);
});
Route::any('/getToken', function(){
    $guzzle = new GuzzleHttp\Client;

    $response = $guzzle->post('http://localhost/oauth/token', [
        'form_params' => [
            'grant_type' => 'client_credentials',
            'client_id' => 'id',
            'client_secret' => 'secret',
            'scope' => 'users bds',
        ],
    ]);

    $obj = \GuzzleHttp\json_decode($response->getBody());
    $token = $obj->{'access_token'};

    echo $token;

    $guzzle = new GuzzleHttp\Client;
    $response = $guzzle->request('GET', 'http://localhost/test', [
        'headers' => [
            'Accept' => 'application/json',
            'Authorization' => 'Bearer '.$token,
            'Scope' => 'users bds',
        ],
    ]);
    echo $response->getStatusCode();
    var_dump($response->getHeader('content-type'));
    echo $response->getBody();
});

Please to help me.

Most helpful comment

I have done all the above but unfortunately Authorization header is still missing

All 7 comments

I think its a private route , so you have to pass access token in the headers as Authorization

If you are using Apache as the web browser you have to check if this is present in the .httaccess file
within the public directory your laravel installation .

RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]

From the provide error message, I think the 'web' route complains it can't find Authorization header. You need to ensure to post a http request to the route, for instance by using curl or any http tool to see how the route handle the request.

One more thing, you may find interesting to check laravel log file via storage/logs/laravel.log

@morloderex : Thank you very much!
I has been fixed this problem with your suggest.

I have done all the above but unfortunately Authorization header is still missing

I still have the same problem, even adding the .htaccess lines

If you put

RewriteCond %{HTTP:Authorization} ^(.*) RewriteRule .* - [e=HTTP_AUTHORIZATION:%1]
in the .htaccess file then make sure
AllowOverride All
is set in the virtual host file for your domain (Apache) to allow the .htaccess file to be run

https://stackoverflow.com/questions/18740419/how-to-set-allowoverride-all

Was this page helpful?
0 / 5 - 0 ratings