dingo / api

A RESTful API package for the Laravel and Lumen frameworks.
BSD 3-Clause "New" or "Revised" License
9.33k stars 1.25k forks source link

Route httpOnly #1689

Open Derjuju opened 4 years ago

Derjuju commented 4 years ago
Q A
Bug? yes
New Feature? no
Framework Lumen
Framework version 6.2.0
Package version 2.4.0
PHP version 73.10

Commit that introduced the dysfonction. https://github.com/dingo/api/commit/3b179dfbb9cdee205c5934efdd37121221034b02#diff-f006d8a8efa02d74816ed58cff7bbf82

Actual Behaviour

Routes declared with or without "https" option are always returned by the router as http:// instead of https://

Illuminate\Routing\RouteUrlGenerator->getRouteScheme

        if ($route->httpOnly()) {
            return 'http://';
        } elseif ($route->httpsOnly()) {
            return 'https://';
        }

if $route->httpOnly() return true it return 'http://'.

But Dingo\Api\Routing\Route->httpOnly

public function httpOnly()
    {
        return in_array('https', $this->action, true)
            || (array_key_exists('https', $this->action) && $this->action['https']);
    }

will always return true and tell to create uri starting with http:// instead of https://

public function httpOnly()
    {
        return in_array('http', $this->action, true);
    }

It breaks all tests which assert that uri are returned with the corresponding https option when they are run from a local computer or a CICD which don't use ssl/https server.

Expected Behaviour

Option "https" must force https:// even if the request is not in secure mode. So httpOnly() should not return true when "https" is used on routes.

$api->version('v1', [
        'namespace' => 'App\Http\Controllers\Api\V1\REST',
        'middleware' => ['api.throttle'],
        'https'

When we put 'https' or 'https'=>true it force the secure mode so as to always return https uri in transformers.

"links":{
        "self":"https://localhost/api/products/0208006"
}

Steps to Reproduce

Create a route with 'https' or 'https'=>true option

$api->version('v1', [
        'namespace' => 'App\Http\Controllers\Api\V1\REST',
        'middleware' => [],
        'https' // or 'https' => true
], function ($api) {
    // product detail
            $api->get('products/{idProduct:\d+}', [
                'as' => 'products.show',
                'uses' => 'ProductController@show',
            ]);
});

From a controller ask to create an uri from the router. app('Dingo\Api\Routing\UrlGenerator')->version('v1')->route('products.show', 0208006)

it returns http://localhost/api/products/0208006 instead of https://localhost/api/products/0208006

Possible Solutions

Revert this commit https://github.com/dingo/api/commit/3b179dfbb9cdee205c5934efdd37121221034b02#diff-f006d8a8efa02d74816ed58cff7bbf82

And applies it on httpsOnly/secure method.

/**
     * Determine if the route only responds to HTTPS requests.
     *
     * @return bool
     */
    public function secure()
    {
        return in_array('https', $this->action, true)
            || (array_key_exists('https', $this->action) && $this->action['https']);
    }