Cookies in browser console is different than cookies fetch from Laravel - laravel

I get two different values from the console and from the Laravel side.
This is how I get from the Laravel side
public function getCookies() {
$cookies = \Cookie::get();
dd($cookies);
}
EDIT 1:
It seems the cookies will be automatically decrypted when get function is called.
Is there any way I could get the original value of the cookies without getting decrypted?
EDIT 2
Resolved this by including the cookies name in except array in EncryptCookies middleware. If you are interested in more of this discussion, can refer
https://github.com/laravel/framework/issues/6679
https://github.com/laravel/framework/pull/9150

Laravel will automatically encrypt and decrypt all cookies.
All cookies created by the Laravel framework are encrypted and signed with an authentication code, meaning they will be considered invalid if they have been changed by the client.
Source: https://laravel.com/docs/5.4/requests#cookies
You can exclude a cookie from the automatic encryption by adding it to the $except array in the EncryptCookies middleware.

Related

SPA Authentication Issues with Sanctum and Postman

I'm currently trying to test an SPA using Laravel 8.19.0 and Postman 7.36.1 but I keep getting an "Unauthenticated" response from a route that's guarded by "auth:sanctum", even though I have logged in correctly.
As far as I can understand, I've followed the documentation fully at https://laravel.com/docs/8.x/sanctum
in order to set Sanctum up to be used for SPA so I've done the following:
Installed Sanctum.
Published the Sanctum config.
Performed a migration.
Included the EnsureFrontendRequestsAreStateful middleware and 'EnsureFrontendRequestsAreStateful::class' to the Http Kernal.
Added my local domains (same top-level domain but 1 with the "test" sub domain and another with "api") to the "stateful domains" option in the Sanctum config file.
Set the "supports_credentials" option in the cors config to "true".
Set my top level domain, prefixed with a "." for the "domain" option in the session config.
Then, I've set Postman up using the guide at https://blog.codecourse.com/laravel-sanctum-airlock-with-postman/
so I've written a script to get the CSRF token from "/sanctum/csrf-cookie" then used said token as the value for the "X-XSRF-TOKEN" in the request header and I can succesfully log in. however, when I try to access a route afterwards that's guarded by the "auth:sanctum" guard, even with the referrer and 'X-XSRF-TOKEN' being set up in the request header I cannot access the route.
After debugging, I can see that $this->auth->guard($guard)->check() is returning false in the authenticate($request, array $guards) method where $guard = "sanctum" in \vendor\laravel\framework\src\Illuminate\Auth\Middleware\Authenticate.php on line 63 because $this->user() is null for the Illuminate\Auth\RequestGuard instance.
Any help or even ideas on things to check would be greatly appreciated as I'm unsure on what to do from here, short of spending a day digging deeper into the request guard object and its instantiation!
Thanks.
The issue a lot folk are seeing when using Postman with Sanctum SPA authentication is that you simply need to add an additional header to your requests, This can be "Referrer" or "Origin" and the value must match the domains set in the sanctum.php config file. e.g. localhost or mysite.test etc.
vendor/laravel/sanctum/src/Http/Middleware/EnsureFrontendRequestsAreStatefull.php in the fromFrontEnd() method is where you can see this requirement. Laravel V8.x and I believe also in Laravel V7.x
Issue has since been resolved and was caused by Postman only saving the "XSRF-TOKEN" and "laravel_session" cookies to the "test" subdomain after logging in (the login URL used this sub domain) and thus not passing them to the "api" subdomain when trying to access the route which was protected by "auth:sanctum". By adding the same cookies to the "api" subdomain via the "Manage Cookies" menu in Postman, the route can now be accessed as intended.

Laravel sessions not saving when called from Postman or Guzzle

I'm experiencing a problem with sessions in Laravel. My project consists about two projects, one an API and another a WebApp. Both with Laravel 5.5.
The problem is that I want to save a session in my API project but it isn't saved. I save the session like this in api.php:
Route::get('test', function () {
session(['data' => "data"]);
session()->save();
});
If I visit: http://mydomain.dev/test through Firefox, I can see the session in the Laravel DebugBar because it has been saved:
If I make a request with Postman to that URL, session doesn't appear in the Laravel DebugBar! It isn't saved.
After some research, I found this question and people say to include in Kernel.php these two lines:
protected $middleware = [
//...
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
];
I have already added those two lines and the problem persists.
The same happens with Guzzle. From my WebApp, I make a GET call to my API. In the method called in the API, I save a session, and when I retrieve the session in another method of the API, I get null because session hasn't been saved!
My suspicion is that Postman and Guzzle problems with sessions are related, and that there's something I'm missing.
My config\session.php files are as default. I know I have as alternative to save sessions in database, but I would prefer to keep it as default, but if I don't have any alternative, I will change my SESSION_DRIVER option from session.php from file to database.
APIs are and should be sessionless/stateless.
They can not handle it.
That's why token based authentications are used.
In order to make you sure about it. Write a route in web.php file and hit it from postman or browser then you will see a session info if any.

Why Laravel5.4 $request->cookie('key') is empty when PHP global var $_COOKIE has cookies

I am trying to read the cookies in Laravel5.4. So I get the cookies after successful validation with third party Authorization server. I am not making the cookies in laravel5.4, but I am reading the cookie value send to me from view/frontend. I can see the values of cookies in Chrome debugger environment as well as from PHP global variable $_COOKIE. They are all set correctly.
However, when I tried to read the same cookie using $request->cookie('key') from controller method... it shows nothing. I also tried Cookie facade to read the value and still nothing. This controller is handling a redirect route which is called by the third party oauth server and this server when it redirects to my URL, it also sets the cookies.
Am I not setting this redirect url route correctly in web.php file in Laravel5.4? This is how it is defined in web.php as below:
Route::get('login/okta/callback',
'Auth\LoginController#handleProviderCallback');
The request object is empty when I dumped the content but $_COOKIE has the data.
Laravel's cookie class encrypts and decrypts the values of its cookies (see the App\Http\Middleware\EncryptCookies middleware). When you have it look at a cookie it didn't set, it's going to try (and fail) to decrypt it.
If you've got a cookie set from outside Laravel, use $_COOKIE to work with it, or add the name of the cookie to the $except array in app/Http/Middleware/EncryptCookies.php so it isn't messed with.

Get a cookie in Laravel 5 middleware

I'm trying to retrieve a cookie from a middleware in Laravel 5.3 but it seems like $request->cookie('language') is empty. I'm guessing that it is only set after the middleware runs.
I read somewhere that I should use \Cookie::queued('language'), but it's still empty.
Is my only option using the $_COOKIE variable?
When do you set this cookie?
Remember that cookies are stored in the browser, so the user needs to get the response in order for you to be able to retrieve the cookie later.
You should be able to get the cookie after the cookie is being set by a response that's successfully sent to the user. Remember also that if you use dd(), that doesn't let the cookie get created, because it skips all cookie headers from being sent to the user.
Another problem you might face for trying to get cookies from middleware is that it might not get decrypted automatically, so you'll have to do it yourself.
Example:
\Crypt::decrypt(Cookie::get('language'))
If someone encounters this problem in 2019 with Laravel 5.8:
You will need to use \Crypt::decryptString(Cookie::get('language')) or \Crypt::decrypt(Cookie::get('language'), false).
Otherwise it will try to unserialize the string and then strange things happen.

Laravel 4: reading cookies set by javascript

If I set a cookie with javascript, how would I read it using Laravel 4?
The reason I'm asking is that the docs say:
All cookies created by the Laravel framework are encrypted and signed
with an authentication code, meaning they will be considered invalid
if they have been changed by the client.
Just use the native PHP command to retrieve cookies: $_COOKIE['cookie'])
Or perhaps you can set the cookie via an AJAX command (rather than JS doing it itself) - and have Laravel set the cookie supplied by JS on its behalf?
This link confirms setting cookies via AJAX - it will just be a variation of that.
In Laravel 5.6 (and maybe earlier versions too):
Specify the cookie name in the $except array within App\Http\Middleware\EncryptCookies.php.
It tells Laravel that those cookies aren't encrypted (and therefore don't need to be decrypted when read).
(P.S. Thanks to https://github.com/laravel/laravel/pull/460#issuecomment-377537771)

Resources