Laravel 5: файл cookie, установленный пользовательским промежуточным программным обеспечением, не читается в контроллере

Я создал веб-сайт с помощью Laravel 5. Чтобы отслеживать пользователей, на которых ссылался какой-либо другой веб-сайт, я использую следующее промежуточное программное обеспечение, которое распознает реферал по параметру запроса и устанавливает файл cookie.

<?php

namespace App\Http\Middleware;

use Closure;

class AffiliateTrackingMiddleware {

    public static $trackingCookieName = "refId";
    public static $trackingURLParameter = "refId";

    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next) {
        $response = $next($request);

        if ($request->has(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingURLParameter)) {

            return $response->withCookie(cookie()->forever(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingCookieName, $request->get(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingURLParameter)));
        }

        return $response;
    }
}

В моем контроллере я хотел бы получить значение файла cookie. Для этого я реализовал следующую функцию. В случае, если файл cookie недоступен, я также проверяю, установлен ли параметр запроса для идентификации реферера.

protected function getAffiliateId($request = null) {

    $affiliateCookieValue = Cookie::get(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingCookieName);

    if (!empty($affiliateCookieValue)) {
        return $affiliateCookieValue;
    } else {
        if ($request !== null) {
            if (!empty($request->get(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingURLParameter))) {
                $affiliateRequestValue = $request->get(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingURLParameter);
                return $affiliateRequestValue;
            } else {
                $affiliateCookieValue = $request->cookie(\App\Http\Middleware\AffiliateTrackingMiddleware::$trackingCookieName);
                return $affiliateCookieValue;
            }
        } else {
            return "";
        }
    }
}

Странно то, что в конструкторе моего контроллера я могу получить правильный идентификатор партнера с помощью файла cookie. Однако, когда я вызываю функцию getAffiliateId из другой функции моего контроллера, значение cookie остается пустым.

Почему я не могу получить значение cookie, установленное в промежуточном программном обеспечении, из любой функции моего контроллера?

В моем браузере я также вижу файл cookie.

Заранее большое спасибо.


добавлено: Код файла Http/Kernel.php

<?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,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\AfterMiddleware::class,
        \App\Http\Middleware\AffiliateTrackingMiddleware::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\Session\Middleware\AuthenticateSession::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,
    ];
}

person LaDude    schedule 19.02.2018    source источник
comment
Покажите нам свой код Kernel.php   -  person Nikola Gavric    schedule 19.02.2018
comment
Я добавил код в свой исходный пост.   -  person LaDude    schedule 19.02.2018
comment
Ваше промежуточное ПО выглядит нормально и правильно добавлено внутри Kernel. Можете ли вы показать нам код рабочей и нерабочей версии getAffiliateId   -  person Nikola Gavric    schedule 19.02.2018
comment
В контроллере я добавил следующий код $this->affiliateID = $this->getAffiliateId($request); (с параметром или без него) либо в function __construct(), либо в функцию public function index(Request $request), которая вызывается маршрутом Route::group(['middleware' => ['web'], 'domain' => env("MY_URL")], function () { Route::get('/', 'MyController@index'); } );.   -  person LaDude    schedule 19.02.2018
comment
Итак, вы хотите использовать промежуточное ПО внутри web вызовов промежуточного ПО, и оно работает, когда вы обращаетесь к нему внутри конструктора вашего контроллера, но не внутри каких-либо функций контроллера?   -  person Nikola Gavric    schedule 19.02.2018
comment
Да. Это правильно.   -  person LaDude    schedule 19.02.2018
comment
Удалите свое промежуточное ПО из $middleware и добавьте его в промежуточное ПО группы web.   -  person Nikola Gavric    schedule 19.02.2018


Ответы (1)


Поскольку вы хотите использовать промежуточное ПО внутри промежуточного ПО web, добавьте его в конец промежуточного ПО группы web, например:

'web' => [
    ...
    \App\Http\Middleware\AffiliateTrackingMiddleware::class,
]

Также убедитесь, что ваши файлы cookie не пусты, когда запрос достигает вашего промежуточного программного обеспечения.

person Nikola Gavric    schedule 19.02.2018
comment
Большой. Теперь это работает! Теперь cookie также зашифрован. Что вы имели в виду, говоря, что ваши куки не пусты...? - person LaDude; 19.02.2018
comment
Неважно, я думал, что вы проверяете и файл cookie, и параметр URL. - person Nikola Gavric; 19.02.2018
comment
Теперь он работает как с файлом cookie, так и с параметром URL. Большое спасибо. - person LaDude; 19.02.2018