Search code examples
phplaravellaravel-5.3laravel-passport

How can I authenticate a request using Laravel Passport having the access token in query string instead of in header?


Authentication works fine using 'middleware' => 'auth:api' on regular endpoints where the client sends the Authorization=Bearer <access_token>.

But now I'd like to handle plain image download requests, without Authorization header, having the access token in the query string like this: GET /picture/my_picture.png?access_token=1234.

I tried something like this in my middleware, but I can't seem to add headers to the Request:

if ($request->has('access_token')) {
    // something like $request->header->set('Authorization', 'Bearer ' . $request->get('access_token'));
}

if ($this->auth->guard($guard)->guest()) {
    // throw exception
}

Can this be done? Maybe intercept or override something/somewhere else?


Solution

  • I had similar issue In your App\Http\Kernal.php

    register your middleware in $middleware and $routeMiddleware

    <?php
    
    namespace App\Http;
    
    use Illuminate\Foundation\Http\Kernel as HttpKernel;
    
    class Kernel extends HttpKernel
    {
        /**
         * The application's global HTTP middleware stack.
         *
         * These middleware are run during every request to your application.
         *
         * @var array
         */
        protected $middleware = [
            \App\Http\Middleware\AddHeaderAccessToken::class,
    
            \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
            \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
            \App\Http\Middleware\TrimStrings::class,
            \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        ];
    
        /**
         * The application's route middleware groups.
         *
         * @var array
         */
        protected $middlewareGroups = [
            'web' => [
                \App\Http\Middleware\EncryptCookies::class,
                \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
                \Illuminate\Session\Middleware\StartSession::class,
                // \Illuminate\Session\Middleware\AuthenticateSession::class,
                \Illuminate\View\Middleware\ShareErrorsFromSession::class,
    //            \App\Http\Middleware\VerifyCsrfToken::class,
                \Illuminate\Routing\Middleware\SubstituteBindings::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 = [
            'addAccessToken' => \App\Http\Middleware\AddHeaderAccessToken::class,
            'auth' => \Illuminate\Auth\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
        ];
    }
    

    Middleware

    <?php
    
    namespace App\Http\Middleware;
    
    use Closure;
    
    class AddHeaderAccessToken
    {
        /**
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {
          if ($request->has('access_token')) {
             $request->headers->set('Authorization', 'Bearer ' . $request->get('access_token'));
            }
            return $next($request);
        }
    }