Prevent Laravel API from processing the token if it comes in the URL as querystring

What I did was to create a middleware in order to reject all requests with "token" as a key param in the querystring.

First we have to create the middleware:

php artisan make:middleware BeforeMiddleware and as you may notice is a before middleware, that means that is going to run before the request hits the application:

<?php

namespace App\Http\Middleware;

use Closure;
use App\Exceptions\BadRequest\RejectTokenAsQuerystring;

class BeforeMiddleware
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request  $request
     * @param \Closure  $next
     *
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        if ($request->token) {
            throw new RejectTokenAsQuerystring('reject_token_as_querystring');
        }
        return $next($request);
    }
}

I also had to add the middleware that I created to my kernel:

<?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 = [
        \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
        \Barryvdh\Cors\HandleCors::class,
    ];

    /**
     * The application's route middleware groups.
     *
     * @var array
     */
    protected $middlewareGroups = [
        'api' => [
            'throttle:60,1',
            'bindings',
        ],
    ];

    /**
     * The application's route middleware.
     *
     * These middleware may be assigned to groups or used individually.
     *
     * @var array
     */
    protected $routeMiddleware = [
        'reject-token-in-url' => \App\Http\Middleware\BeforeMiddleware::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,
        'jwt.auth' => \Tymon\JWTAuth\Middleware\GetUserFromToken::class,
        'jwt.refresh' => \Tymon\JWTAuth\Middleware\RefreshToken::class,
    ];
}

And finally the middleware as is being defined globally can be used in the definition of my routes as:

<?php

/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/

Route::group(
    [
        'domain' => getenv('API_DOMAIN'),
        'middleware' => ['cors', 'reject-token-in-url'],
        'prefix' => '/v1',
        'namespace' => 'V1'
    ],
    function () {
    }
);

I also have implemented my own definition of error, so I have a list of all possible errors that I want to trigger in my application, and they are defined as follows in my config/errors.php file:

<?php

return [
    "reject_token_as_querystring" => [
            "title"  => "Reject token as querystring.",
            "detail"  => "Token MUST be passed in the Header of the request."
    ]
];

Then you need to define your custom Exception class:

<?php

namespace App\Exceptions;

use Exception;

abstract class CustomException extends Exception
{
    /**
     * The id of the error that is being triggered.
     *
     * @var string
     */
    protected $errorId;

    /**
     * Status code for the triggered error.
     *
     * @var string
     */
    protected $status;

    /**
     * Title of the error.
     *
     * @var string
     */
    protected $title;

    /**
     * Detailed description about the error.
     *
     * @var string
     */
    protected $detail;

    /**
     * Instantiate a new Exception with the provided message.
     *
     * @param @string $message
     *
     * @return void
     */
    public function __construct($message)
    {
        parent::__construct($message);
    }

    /**
     * Get the status
     *
     * @return Int
     */
    public function getStatus()
    {
        return (int) $this->status;
    }

    /**
     * Return the Exception as an array
     *
     * @return Array
     */
    public function toArray()
    {
        return [
            'id'     => $this->id,
            'status' => $this->status,
            'title'  => $this->title,
            'detail' => $this->detail
        ];
    }

    /**
     * Build the Exception.
     *
     * @param array $args
     *
     * @return string
     */
    protected function build(array $args)
    {
        $this->id = array_shift($args);
        $error = config(sprintf('errors.%s', $this->id));
        $this->title  = $error['title'];
        $this->detail = vsprintf($error['detail'], $args);
        return $this->detail;
    }
}

And you will use that class to extend your custom errors:

<?php

namespace App\Exceptions\BadRequest;

use App\Exceptions\CustomException;

class BadRequestException extends CustomException
{
    /**
     * Status error number.
     *
     * @var string
     */
    protected $status = '400';

    /**
     * Instantiate a new 'bad request exception'.
     *
     * @return void
     */
    public function __construct()
    {
        $message = $this->build(func_get_args());

        parent::__construct($message);
    }
}

In order to create the class that holds the error itself:

<?php

namespace App\Exceptions\BadRequest;

use App\Exceptions\BadRequest\BadRequestException;

class RejectTokenAsQuerystring extends BadRequestException
{

}

Finally if you try to request info with the token key in the url you will get:

{
  "id": "reject_token_as_querystring",
  "status": "400",
  "title": "Reject token as querystring.",
  "detail": "Token MUST be passed in the Header of the request."
}

enter image description here