3

I am building a laravel API and i need to be able to only accept requests of type 'application/json' when data is being posted. Any other content-types should return a 406 'Not Acceptable' response.

I am aware I could put in some middleware to check for this however I was wondering if there is a better way this could be accomplished?

Thanks

SamBremner
  • 793
  • 2
  • 10
  • 22

3 Answers3

3

Use this middleware:

class WeWantJsonMiddleware
{
    /**
     * We only accept json
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if (!$request->isMethod('post')) return $next($request);


        $acceptHeader = $request->header('Accept');
        if ($acceptHeader != 'application/json') {
            return response()->json([], 406);
        }

        return $next($request);
    }
}

(modification of https://stackoverflow.com/a/44453966/2311074)

And add it in App\Http\Kernel to $middleware to check for every post request. If you only want to check for API posts request, just put it in $middlewareGroups['api'].

Adam
  • 25,960
  • 22
  • 158
  • 247
  • Thanks for your answer, this is fine if all of the post routes are together in the routes file but i have a structure that is already grouping with a number of prefixes for the routes so if i add this middleware i would have to specifically add this middleware to each post route. As i know all post routes will need this check is there a way i can apply this globally? – SamBremner May 07 '20 at 16:08
  • @SamBremner sorry I misread your comment, you want to apply it to all `post` routes? That is also possible let me quickly change my answer – Adam May 07 '20 at 16:09
  • @SamBremner I have upded my answer now – Adam May 07 '20 at 16:13
  • 1
    Perfect that is exactly what i need. Thanks :) – SamBremner May 07 '20 at 16:14
  • @SamBremner Thank you for checking :) I got now 10.000 points woho – Adam May 07 '20 at 16:15
1

Here's my two cents:

class JsonMiddleware
{
    /**
     * Accept JSON only
     *
     * @param Request $request
     * @param Closure $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        $header = $request->header('Accept');
        if ($header != 'application/json') {
            return response(['message' => 'Only JSON requests are allowed'], 406);
        }

        if (!$request->isMethod('post')) return $next($request);

        $header = $request->header('Content-type');
        if (!Str::contains($header, 'application/json')) {
            return response(['message' => 'Only JSON requests are allowed'], 406);
        }

        return $next($request);
    }
}
Neash
  • 55
  • 1
  • 1
  • 6
1

Simple use 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 POST request is JSON
        if ($request->isMethod('post') && !$request->expectsJson()) {
            return response(['message' => 'Only JSON requests are allowed'], 406);
        }

        return $next($request);
    }
}
Quang Tam
  • 21
  • 1