cookies are not set if you send request from different domain - php

Sanctum Version: 2.11.2
Laravel Version: 8.55.0
PHP Version: 7.4.20
Laravel is running on: http://127.0.0.1:8000
front end (vue) is running on: http://localhost:3000
I put all following in my .env file
COOKIE_SAME_SITE_POLICY=strict
SESSION_SECURE_COOKIE=false
SESSION_DOMAIN='.127.0.0.1'
SANCTUM_STATEFUL_DOMAINS='.localhost,.localhost:3000,127.0.0.1,127.0.0.1:8000,::1'
When I'm trying to authenticate from a different domain it gives 419 error CSRF token mismatch, the first request "http://127.0.0.1:8000/sanctum/csrf-cookie" which must set the cookies does not set anything however if I try the same request inside laravel instance it sets the cookies and works as expected
how every the same request sets the cookies successfully in postman
Steps To Reproduce:
install laravel "composer create-project laravel/laravel sanctum"
change 'supports_credentials' => false, to 'supports_credentials' => true, from /config/cors.php
set up the vue app on "http://localhost:3000" and send a request to "http://127.0.0.1:8000/sanctum/csrf-cookie" and it will not set the cookies.

You cannot set a cookie for a different domain for security reasons

Related

vue js spa and laravel sanctum: cannot set crsf-cookie

CONTEXT AND GOAL
I have my laravel backend running on backend.domain
I have a vuejs spa trying to logging in from 'external.app.domain'
I need that vuejs spa can login, obatain A NEW token for the user, to, then, use for subsequent calls.
WHAT I DID
I am following this: https://laravel.com/docs/9.x/sanctum#csrf-protection
The call to sanctum/csrf-cookie works, but I got this from chrome
Axios in vue app is using
withCredentials: true,
Backend cors.php file has
'supports_credentials' => true,
Backend sanctum.php file has external.app.domain in the stateful array
THE MAIN PROBLEM
The problem is that calling /login to obtain a token I got this
CSRF token mismatch.
Simple question
What else must I do !?
SOLVED
I had to remove the middleware of sanctum in api.
I previously enabled because I was trying other way to use Sanctum itself.

419 Page Expired In Laravel Even after adding CSRF token

I am working on a Laravel 8 Framework,
I have added the application on the live Cpanel server and then it started showing below Error:
419 PAGE EXPIRED
I know generally missing CSRF token will be the main issue but in this, I have added the CSRF token,
I am using LARAVEl blade syntax so adding LARAVEL blade form syntax the "Token" (CSRF) will get added directly.
{{ Form::open( [ "url" => \URL::route("front.login.check"), "autocomplete"=>false,"id" => "login_form" ] ) }}
This will add the CSRF automatically,
I have tried adding directly,
But every POST request end up on the 419 PAGE EXPIRED page.
What do I have checked already?
CSRF Token Is not missing in the Form
I have checked middleware also but this request did not reach the middleware after form submit it will take to the 419 page
Also try to php artisan cache:clear and dump-autoload command but the issue is still.
Added 755 permission to storage, vendor and cache folder also.
Please help me on this What next should I need to check for solve this issue?
Laravel "419 Page Expired" Error Troubleshooting Steps
Apply/go through all steps up to "step 12" BEFORE testing your application for this error.
Increase your session expiration time (I.e. 24 hours).
Make sure that the "session domain" is the same as the "app URL".
Ensure that the session cookies are sent back to the server for both "HTTP" & "HTTPS" browser connections.
.env file contents applying the above 3 steps.
Change myapp.local to your application domain.
APP_URL="http://myapp.local"
SESSION_LIFETIME=1440
SESSION_DOMAIN=myapp.local
SESSION_SECURE_COOKIE=false
Make sure you submit a CSRF token along with your (PUT/POST/DELETE/etc.) HTTP requests.
(I.e: Ensure that this request parameter is submitted along with your HTML form requests <input type="hidden" name="_token" value="{{ csrf_token() }}" />).
If in case you make AJAX requests in your application, you may configure ALL AJAX requests to send the CSRF token at all times.
Add this "<meta> tag" inside the <head> tag of all your master VIEW templates/layouts. I.e: resources/views/layouts/app.blade.php and resources/views/layouts/guest.blade.php and resources/views/welcome.blade.php
<meta name="csrf-token" content="{{ csrf_token() }}">
Then, define the required HTTP request headers and recompile your app's static assets (npm run dev). resources/js/app.js
$.ajaxSetup({
headers: {
"X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content"),
"X-Requested-With": "XMLHttpRequest"
}
});
Regenerate your application key automatically. (I.e: php artisan key:generate).
Clear your application cache. (I.e: php artisan cache:clear).
Confirm that the application caller has read & write permissions in the application's "sessions" & "cache" folder. (I.e: chmod -R 755 "storage/framework/sessions" && chmod -R 755 "bootstrap/cache").
Addendum 1:
If in case you have Laravel Sanctum installed and enabled, add your application domain among the whitelist of "sanctum stateful domains".
.env file contents
Change myapp.local to your application domain.
SANCTUM_STATEFUL_DOMAINS="myapp.local"
Addendum 2:
Ensure that your "session driver" isn't empty. The default value is "file".
.env file contents
SESSION_DRIVER=file
Addendum 3:
Disable the browser cache. This may be beneficial during your development process.
Open your web browser, navigate to your application's home page, reload the current page, ignoring cached content. (I.e: On Windows: Shift + F5 or Ctrl + Shift + r and on Mac: ⌘ + Shift + r).
TEST YOUR APP! Check if you still receive the error.
Addendum 4 (Optional):
Only perform the steps below if you reached step 12 and are still having the same error.
A. Clear ALL web browser cache & cookies. TEST YOUR APP!
B. Open an entirely different web browser and test again. If you've been using Google Chrome / Safari all along, try testing using Firefox. TEST YOUR APP!
C. Restart your computer and test again. TEST YOUR APP!
1- php artisan route:clear
2- go to CSRF middleware and try to add "*" to your except array
When this happened to me it was because I forgot to add 'name' attribute to my input in the form

Laravel - Nexmo "Please provide Nexmo API credentials" Error

I want send send SMS with laravel-Nexmo. I already configure all the settings. But when i try to send a SMS it gives this error
Please provide Nexmo API credentials. Possible combinations: api_key +
api_secret, api_key + signature_secret, private_key + application_id,
api_key + api_secret + private_key + application_id, api_key +
signature_secret + private_key + application_id
I added nexmo api_key & secret_key in services.php , .env file and nexmo.php
I also added this;
curl.cainfo="C:\xampp\apache\bin\cacert.pem" in php.ini file
What is the reason for this error and how to fix this? Thank you!
I already configure all the settings.
What exact settings did you configure? The error means that the library could not determine an appropriate set of credentials to use for Nexmo.
If you are sending an SMS, all you need to set is NEXMO_KEY and NEXMO_SECRET. I would try setting just those two environment options and see if you get the same error. If you are using request signing by setting NEXMO_SIGNATURE_SECRET, I would disable that for the time being just to check that sending a base SMS works.
Once you update your settings, I would make sure that the cache is cleared using artisan config:clear to clear the cache, which should allow the settings to be picked up on the next page load.
I ran into the same issue, and was able to fix it.
Cause
It looks to me like laravel/nexmo-notification-channel has been updated, but Laravel itself hasn't (yet).
According to the Laravel [6.x] pull request:
composer require laravel/nexmo-notification-channel
This will also install the nexmo/laravel package. This package includes its own configuration file. You can use the NEXMO_KEY and
NEXMO_SECRET environment variables to set your Nexmo public and secret
key.
https://github.com/laravel/docs/pull/5519/files?short_path=7c04c15#diff-7c04c1591e2821d381785df56ebd70af
Solution
It was easy, just copy this new nexmo.php config file into your config folder: https://github.com/Nexmo/nexmo-laravel/blob/master/config/nexmo.php
As long as you have the NEXMO_KEY and NEXMO_SECRET set in your .env file, it should now work.
I am using Laravel 8 and faced the same issue. Then I realize that I was adding
NEXMO_KEY=your key here
NEXMO_SECRET=your secret here
to .env.example file. I just added it to .env file and re-config the cache by php artisan config:cache
Now it's working.
Note: you should get your api_key and secret rom vonage.com

Laravel 419 Error - VerifyCsrfToken issue

I have multiple Laravel sites hosted on the same server. With the latest site I've created, the contact form refuses to submit without throwing a 419 error. I have set up the routing in my web.php file just like the other websites, which have live, working contact forms, and I'm generating and sending the token exactly the same way - with {{ csrf_field() }}.
I found an answer to a similar question stating that you can disable Csrf checking by adding entries to the $except array in app/Http/Middleware/VerifyCsrfToken.php. I have verified that this does indeed resolve the 419 error:
protected $except = [
'contact',
'contact*',
];
But of course I wish to keep the Csrf functionality, and I only updated the $except array for troubleshooting value.
Does anyone know what may be different about the new Laravel environment that would have this 419 behavior despite passing the generated token? I have tried updating a number of ENV settings and toggling different things, but nothing other than modifying the $except array has had any influence on the issue.
Update
Since there has been a bit of discussion so far, I figured I'd provide some additional info and code.
First, this is an ajax form, but don't jump out of your seat just yet. I have been testing the form both with and without ajax. If I want to test with ajax, I just click the button that's hooked up to the jQuery listener. If not, I change or remove the button's ID, or run $("#formName").submit(); in the console window.
The above (ajax, old-fashioned submit, and the jquery selector with .submit();) all result in the exact same response - a 419 error.
And for the sake of completeness, here's my ajax code which is working on all of the other websites I'm hosting. I define a postData array to keep it all tidy, and I added a console.log() statement directly after it to (again) confirm that token is generated just fine and is being passed correctly with the request.
var postData = {
name: $("#name").val(),
email: $("#email").val(),
message: $("#message").val(),
_token: $("input[name=_token]").val()
};
console.log(postData);
$.post("/contact", postData, function (data) {
...
Any ideas? Could there be a configuration issue with my ENV or another file?
Progress Update!
Because the other sites are working just fine, I cloned an old site and simply overwrote the files that I changed for the new website, and bam! It's working now. Doing a little bit more digging, I ran php artisan --version on the cloned version of the site versus the non-working version, and here are the results:
Working Version: Laravel Framework 5.7.3
Non-working Version: Laravel Framework 5.7.9
Perhaps this is a bug with Laravel? Or perhaps some packages on my server are out of date and need to be updated to work with the new version of Laravel?
TLDR: This post contains lots of potential issues and fixes; it is intended for those scouring for related bonus information when stuck.
I just encountered this error using Laravel Sanctum in what looks like improperly setup middleware. Sanctum uses the auth:sanctum middleware for the guard, which is some kind of extension of the auth guard of which Laravel uses as the default, but session is handled by the web middleware group.
I can't exactly verbalize some of this internal-Laravel stuff; I am more experienced with JavaScript than PHP at the moment.
In my api.php file, I had the login/register/logout routes, and in my Kernel.php file, I copied \Illuminate\Session\Middleware\StartSession::class, from the web group into the api group.
I had to do that to fix my login unit test that was throwing an error about "Session store not on request". Copying that allowed me my postJson request to work in the unit test, but sometime later, I started seeing 419 CSRF error posting from the JavaScript app (which is bad because it worked fine earlier).
I started chasing some filesystem permission red-herring in the /storage/framework/sessions folder, but the issue wasn't that (for me).
I later figured out that with Laravel Sanctum and the default AuthenticatesUsers trait, you must use the web guard for auth, and the auth:sanctum middleware for protected routes. I was trying to use the api guard for auth routes and that was central to my 419 errors with the AuthenticatesUsers trait.
If anyone gets 419 while CSRF was working or should work, I recommend doing some \Log::debug() investigations at all the key points in your system where you need these to work:
Auth::check()
Auth::user()
Auth::logout()
If you get strange behaviour with those, based on my observations, there is something wrong with your config related to sessions or something wrong with your config related to web, api guards.
The guards have bearing on the AuthManager guard which maintains state over multiple requests and over multiple unit tests.
This is the best description I found, which took over a week for me to discover:
Method Illuminate\Auth\RequestGuard::logout does not exist Laravel Passport
As a random final example, if your session is somehow generating the CSRF token using data from the web middleware group while your routes are set to use api, they may interpret the received CSRF incorrectly.
Besides that, open Chrome dev tools and goto the Applications tab, and look at the cookies. Make sure you have the XSRF-TOKEN cookie as unsecure (ie: not httpOnly).
That will allow you to have an Axios request interceptor such as this:
import Cookies from 'js-cookie';
axios.interceptors.request.use(async (request) => {
try {
const csrf = Cookies.get('XSRF-TOKEN');
request.withCredentials = true;
if (csrf) {
request.headers.common['XSRF-TOKEN'] = csrf;
}
return request;
} catch (err) {
throw new Error(`axios# Problem with request during pre-flight phase: ${err}.`);
}
});
That is how my current Laravel/Vue SPA is working successfully.
In the past, I also used this technique here:
app.blade.php (root layout file, document head)
<meta name="csrf-token" content="{{ csrf_token() }}">
bootstrap.js (or anywhere)
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
const token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
In my opinion, most problems will stem from an incorrect value in one or more of these files:
./.env
./config/auth.php
./config/session.php
Pay close attention to stuff like SESSION_DOMAIN, SESSION_LIFETIME, and SESSION_DRIVER, and like I said, filesystem permissions.
Check your nginx access.log and/or error.log file; they might contain a hint.
just found your issue on the framework repo.
It is not a laravel issue, your installation is missing write permissions on the storage folder, thus laravel can't write session, logs, etc.
You get a 419 error because you can't write to the files, thus you can't create a sessionn, thus you can't verify the csrf token.
Quick fix: chmod -R 777 storage
Right fix: move your installation to a folder where nginx/apache/your user can actually write.
If you are using nginx/apache, move you app there and give the right permissions on the project (chown -R www-data: /path-to-project)
If you are using php artisan serve, change it's permissions to your user: chown -R $(whoami) /path-to-project
You get it, let writers write and you're good.
Probably your domain in browser address bar does not match domain key in config/session.php config file or SESSION_DOMAIN in your env file.
I had the same issue, but the problem in my case was https. The form was on http page, but the action was on https. As a result, the session is different, which is causing the csrf error.
run this command
php artisan key:generate
I used the same app name for staging and prod, being staging a subdomain of prod. After changing name of app in staging it worked
We had this issue, it turned out that our sessions table wasn't correct for the version of Laravel we were using. I'd recommend looking to see if it's being populated or remaining empty (like ours was).
If it's empty, even when you have people visiting the site, I'd say that's what the issue is.
(If you're not using a database to store your sessions, obviously I'd suggest checking wherever you are instead.)

Laravel 5.2.11, sessions are not working, session cookie not being set

I'm new to Laravel, I have learned about the models, views, blade, controllers and routes and how they work together. So far everything has been working smoothly.
I'm having trouble with sessions though.
When I use the AuthController that comes with Laravel and hit auth/register with a POST request, the data for the user that I register does get inserted into the users table (using mysql) and I do get back a response with the "Location" header redirecting to / like it does out of the box. It redirects like it should. But in the same response there is no "Set-Cookie" header set/sent. The session part of Laravel is not working properly for me. This is the same for a POST to auth/login, it authenticates properly and redirects to the profile page but no session cookie is sent back in the response.
I'm using:
Laravel 5.2.11
PHP 5.5.9
xubuntu 14.04 (Ubuntu)
Linux kernel 3.19.0-42-generic
Composer 1.0
All of the php modules that Laravel requires are installed. I'm running the app with php's built in web server. I run that with sudo. The exact command I run is this:
sudo php -S localhost:8888 -t public/
All routes are being responded to properly.
I have tried both ways of installing Laravel that the installation docs recommend, through the laravel executable and composer create-project. Still no cookies set either way. I have made all the files and directories of the laravel project mod 777. The app key is set in .env if that makes any difference.
The config/session.php file is using the file driver for the session.
There are no session files in the storage/framework/sessions directory after setting a session.
When I try setting a session myself with the session function like it states in the docs:
session(['sesskey' => 'somevalue']);
Again no "Set-Cookie" header is sent in the response and no session file is created. There are no error messages reported back either I should add.
When I do set a session key with the session function like above I can get that value back however and echo it back to the browser like so:
echo session('sesskey');
So it does seem to save it at least in php's memory.
When I try setting a cookie using the withCookie method, I do get the proper response with the Set-Cookie header set:
return response()->view('welcome')->withCookie(cookie("test", "val" , 3600));
I tried going down the illuminate rabbit hole to see if I could find a problem but that is a bit over my head atm.
Any help would be much appriciated, thanks!
in laravel 5.2 you need to use "web" middleware for your problem,like that
Route::group(['middleware' => ['web']], function () {
//
});
use middleware for the request \Illuminate\Session\Middleware\StartSession::class
Route::group(['middleware' => [\Illuminate\Session\Middleware\StartSession::class]], function () {
});

Categories