0

I created a website with Laravel 5. In order to keep track of users that were referred to by some other website I use the following middleware that recognizes the referral by a request parameter and sets a 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;
    }
}

In my controller I would like to retrieve the value of the cookie. I implemented the following function for that. For the case that there is no cookie available I also check if there is a request parameter set to identify the referrer.

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 "";
        }
    }
}

The strange thing now is that within the constructor of my controller I am able to retrieve the correct affiliate id by cookie. However, when I call the function getAffiliateId from within another function of my controller the cookie value remains empty.

Why is it not possible for me to retrieve the cookie value set up in the middleware from any function in my controller?

In my browser I can also see the cookie.

Thanks a lot in advance.


added: The code of the 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,
    ];
}
LaDude
  • 1,383
  • 1
  • 11
  • 27
  • Show us your `Kernel.php` code – Nikola Gavric Feb 19 '18 at 09:45
  • I added the code in my original post. – LaDude Feb 19 '18 at 09:48
  • Your middleware seems fine and is correctly added inside `Kernel`. Can you show us the code for working and not working version of `getAffiliateId` – Nikola Gavric Feb 19 '18 at 10:01
  • Within the Controller I added the following code `$this->affiliateID = $this->getAffiliateId($request);` (with or without the parameter) either within the `function __construct()` or within the function `public function index(Request $request)` that is called by the Route `Route::group(['middleware' => ['web'], 'domain' => env("MY_URL")], function () { Route::get('/', 'MyController@index'); } );` – LaDude Feb 19 '18 at 10:05
  • So you want to use your middleware inside of `web` middleware calls and it works when you access it inside of your controller constructor but not within any controller functions? – Nikola Gavric Feb 19 '18 at 10:08
  • Yes. That is correct. – LaDude Feb 19 '18 at 10:09
  • Remove your middleware from `$middleware` and append it into `web` group middleware – Nikola Gavric Feb 19 '18 at 10:16

1 Answers1

1

Since you want to use your middleware inside of your web middleware, append your middleware at the end of web group middleware, like so:

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

Also make sure that your cookies are not empty when the request hits your middleware

Nikola Gavric
  • 3,507
  • 1
  • 8
  • 16