Sunday, March 19, 2017

How to prevent Laravel API from processing parameters on query-string?

I would like to restrict my Laravel API from processing parameters as query-string when trying to authenticate the user. I've been trying with POSTMAN and all the time I'm able to get the token from my API whether I put the credentials on the body or as query-string in the url.

I'm using Laravel 5.3 and PHP 7.1.0

Here is the POST by using query-string:

enter image description here

Here is the POST by using parameters in the body:

enter image description here

I have configured my CORS by using laravel-cors:

<?php

return [
   'defaults' => [
       'supportsCredentials' => false,
       'allowedOrigins' => [],
       'allowedHeaders' => [],
       'allowedMethods' => [],
       'exposedHeaders' => [],
       'maxAge' => 0,
       'hosts' => [],
   ],

   'paths' => [
       'v1/*' => [
           'allowedOrigins' => ['*'],
           'allowedHeaders' => ['Accept', 'Content-Type'],
           'allowedMethods' => ['GET', 'POST', 'PUT', 'PATCH', 'DELETE'],
           'exposedHeaders' => ['Authorization'],
           'maxAge' => 3600,
       ],
   ],
];

My routes (the relevant ones):

Route::group(
    [
        'domain' => getenv('API_DOMAIN'),
        'middleware' => 'cors',
        'prefix' => '/v1',
        'namespace' => 'V1'
    ],
    function() {
        /* AUTHENTICATION */
        Route::post(
            'signin',
            'AuthenticationController@signin'
        )->name('signin');

        Route::post(
            'signup',
            'AuthenticationController@signup'
        )->name('signup');
    }
);

When listing my routes php artisan route:list I get:

------------------------------------------------------------------------------------------------------------------------------------
| Domain    | Method | URI           | Name       | Action                                                            | Middleware |
| localhost | POST   | api/v1/signin | api.signin | App\Http\Controllers\API\V1\AuthenticationController@signin       | api,cors   |
| localhost | POST   | api/v1/signup | api.signup | App\Http\Controllers\API\V1\AuthenticationController@signup       | api,cors   |
------------------------------------------------------------------------------------------------------------------------------------

My AuthenticationController:

<?php

namespace App\Http\Controllers\API\V1;

use Illuminate\Http\Request;

use App\Http\Controllers\Controller;
use Tymon\JWTAuth\Exceptions\JWTException;
use App\Http\Requests;
use JWTAuth;

class AuthenticationController extends Controller
{
    public function __construct()
    {
        $this->middleware('jwt.auth', ['except' => ['signin', 'signup']]);
    }

    public function signin(Request $request)
    {
        $credentials = $request->only('email', 'password');
        try {
            if (! $token = JWTAuth::attempt($credentials)) {
                return response()->json(
                    [
                        'error' => 'invalid_credentials'
                    ],
                    401
                );
            }
        } catch (JWTException $e) {
            return response()->json(
                [
                    'error' => 'could_not_create_token'
                ],
                500
            );
        }
        return response()->json(compact('token'));
    }

    public function signup(Request $request)
    {
        try {
            $user = User::where(['email' => $request["email"]])->exists();
            if($user)
            {
                return Response::json(
                    array(
                        'msg' => "Email {$request->email} already exists"
                    ),
                    400
                );
            }
            $user = new User;
            $user->create($request->input());
            return Response::json(
                array(
                    'msg' => 'User signed up.'
                )
            );
        } catch (Exception $exception) {
            return Response::json(
                array(
                    'success' => false,
                    'exception' => $exception
                )
            );
        }
    }
}

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 = [
        '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,
        ],

        '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.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 I placed the respective configuration on config/app.php:

        ...
        /*
         * Package Service Providers...
         */
        Barryvdh\LaravelIdeHelper\IdeHelperServiceProvider::class,
        Collective\Html\HtmlServiceProvider::class,
        Laracasts\Flash\FlashServiceProvider::class,
        Prettus\Repository\Providers\RepositoryServiceProvider::class,
        \InfyOm\Generator\InfyOmGeneratorServiceProvider::class,
        \InfyOm\CoreTemplates\CoreTemplatesServiceProvider::class,

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

        Tymon\JWTAuth\Providers\JWTAuthServiceProvider::class,
        Barryvdh\Cors\ServiceProvider::class,
        Asvae\ApiTester\ServiceProvider::class,
    ],

I don't want to use dingoapi.

I checked these resources:

Last but not least, my composer.json:

{
    "name": "laravel/laravel",
    "description": "The Laravel Framework.",
    "keywords": ["framework", "laravel"],
    "license": "MIT",
    "type": "project",
    "require": {
        "php": "^7.1.0",
        "laravel/framework": "5.3.*",
        "barryvdh/laravel-ide-helper": "v2.2.1",
        "laravelcollective/html": "v5.3.0",
        "infyomlabs/laravel-generator": "5.3.x-dev",
        "infyomlabs/core-templates": "5.3.x-dev",
        "infyomlabs/swagger-generator": "dev-master",
        "jlapp/swaggervel": "2.0.x-dev",
        "doctrine/dbal": "2.3.5",
        "league/flysystem-aws-s3-v3": "1.0.13",
        "tymon/jwt-auth": "0.5.9",
        "barryvdh/laravel-cors": "v0.8.2",
        "fzaninotto/faker": "~1.4",
        "caouecs/laravel-lang": "3.0.19",
        "asvae/laravel-api-tester": "^2.0"
    },
    "require-dev": {
        "fzaninotto/faker": "~1.4",
        "mockery/mockery": "0.9.*",
        "phpunit/phpunit": "~5.7",
        "symfony/css-selector": "3.1.*",
        "symfony/dom-crawler": "3.1.*"
    },
    "autoload": {
        "classmap": [
            "database"
        ],
        "psr-4": {
            "App\\": "app/"
        }
    },
    "autoload-dev": {
        "psr-4": {
            "Tests\\": "tests/"
        }
    },
    "scripts": {
        "post-root-package-install": [
            "php -r \"file_exists('.env') || copy('.env.example', '.env');\""
        ],
        "post-create-project-cmd": [
            "php artisan key:generate"
        ],
        "post-install-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postInstall",
            "php artisan optimize"
        ],
        "post-update-cmd": [
            "Illuminate\\Foundation\\ComposerScripts::postUpdate",
            "php artisan optimize"
        ]
    },
    "config": {
        "preferred-install": "dist"
    }
}



via nisevi

Advertisement