Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set header for all requests in route group

I'm creating an API with Laravel 5.4 and it all works well. I've used the following middleware => auth:api like this

Route::group(['middleware' => 'auth:api'], function(){ 
    Route::get('URIValue', ControllerName@action) //Example
});

I've tested it with postman and it works well when the request header contains the following keys and values :

  • Authorization:Bearer api_token
  • Accept:application/json

When the api_token is invalid the unauthenticated function of the Handler class is executed. The default response that laravel returns is

'error' => 'Unauthenticated' // in JSON format

But when the Accept header is not set, laravel returns a view by default. But with an API, views are not acceptable.

How can I force laravel to check that the Accept header is set with the right value (in this case the value must be => accept/json) for every single request for the routes that are in the route group?

Something like:

protected function mapApiRoutes()
{
    Route::prefix('api')
          ->middleware('api')
          ->namespace($this->namespace)
          ->header('Accept' => 'application/json') //this
          ->group(base_path('routes/api.php'));
}

or

Route::group(['middleware'  => 'auth:api', 
              'headers'     => ['Accept' => 'application/json']
             ], function(){ 
                    Route::get('URIValue', ControllerName@action) //Example
             });
like image 577
Gloire Avatar asked Jun 09 '17 08:06

Gloire


2 Answers

You can create a middleware for that.

You'll have check and enforce the Accept header so Laravel will output json no matter what..

class WeWantJson
{
    /**
     * We only accept json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $acceptHeader = $request->header('Accept');
        if ($acceptHeader != 'application/json') {
            return response()->json([], 400);
        }

        return $next($request);
    }
}

And in your App\Http\Kernel you can add the middleware to you api group. Then there's no need to manually add it in the routes/routegroups.


Edit:

You could also add a middleware to enforce json no matter what...

class EnforceJson
{
    /**
     * Enforce json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $request->headers->set('Accept', 'application/json');

        return $next($request);
    }
}
like image 197
Robert Avatar answered Oct 16 '22 06:10

Robert


You can use simple middleware like this

class OnlyAcceptJsonMiddleware
{
    /**
     * We only accept json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
       // Verify if request is JSON
        if (!$request->expectsJson()) {
            return response(['message' => 'Only JSON requests are allowed'], 406);
        }

        return $next($request);
    }
}

And in your App\Http\Kernel you can add the middleware to you api group or any group that you wanna use.

like image 31
Quang Tam Avatar answered Oct 16 '22 06:10

Quang Tam