Laravel Sanctum - 419 CSRF token mismatch using a Vue SPA - php

There are loads of posts around the Internet related to this so I apologise if I've missed the answer here, but I seem to be going round in circles even after looking at all the existing answers. I'm clearly overlooking something.
I have a Laravel app which was recently upgraded from 6 to 8 which is being served locally under api.company-name.local. I also have a separate Vue front-end SPA being served under app.company-name.local:8080. I seem to get a successful response after getting the cookie, however when I hit my login endpoint I get a 419 - CSRF Token Mismatch response.
Setup
The Laravel app sits containerised locally with Docker, front-end simply being served up with npm run serve and I have entries in my hosts file for:
127.0.0.1 api.company-name.local
127.0.0.1 app.company-name.local
Front-End
I make a request to api.company-name.local/sanctum/csrf-cookie from within the front-end app which returns a 204 response, and then make a POST request to my login endpoint to authenticate the user.
const login = async () => {
await axios.get('/sanctum/csrf-cookie')
.then(() => {
axios.post('/loginUser', {
username: 'my-username',
password: 'my-password',
})
})
}
Observing the login POST request, I can see two cookies being sent in the request headers.
In my main.ts file I have configured the following axios defaults:
axios.defaults.withCredentials = true
axios.defaults.baseURL = 'http://api.my-company.local'
Back-End
I have updated my .env file to the following:
SESSION_DRIVER=cookie
SESSION_DOMAIN=app.company-name.local (have also tried .company-name.local)
SANCTUM_STATEFUL_DOMAINS=app.company-name.local:8080
I have added the appropriate middleware to the kernel:
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
My cors.php file is updated with these details:
'paths' => [
'api/*',
'sanctum/csrf-cookie',
'/loginUser',
'/logout',
],
'supports_credentials' => true,
When the user hits that login endpoint they'll hit this particular route setup, which uses the web middleware:
Route::group([
'module' => 'Users',
'middleware' => ['web'],
], function () {
Route::post('/loginUser', 'UsersController#login');
});
It doesn't seem to matter what I change here, I still end up with the 419 so I'm missing something here. Can anyone shed any light on what the problem could be?

Related

Laravel Session Authentication in localhost?

can anyone teach me why i cant authenticate my laravel session iny my localhost? (database driven!)
Im actually using the auth service from breezer.
**
my first question is: is it possible to auth a user on a localhost by laravels sessions authentication? For me it worked only in production.
My Frontend goes with Angular.
My trys to authenticate and log the user with:
Auth::guard('api')->check()
Auth::guard('web')->check()
Auth::guard()->check()
failed all, f.E gives me a null error.
auth defaults runs on:
defaults' => [
'guard' => 'api',
'passwords' => 'users',
],
my ENV datas looks like:
SESSION_DRIVER=database
SESSION_LIFETIME=180
SESSION_DOMAIN=localhost:4200
APP_URL=localhost:8000
APP_ENV=local

Laravel Fortify and JSON based registering result in CRSF mismatch

I'm currently toying with Laravel 9.x and Fortify.
For the starter here my environnement :
Laravel 9.19
Fortify 1.14
Postgre 15
I try to achieve something I thought was possible from reading the Fortify doc, using a third-party UI (e.g.: Mobile App) to register and login user.
So, following the documentation guide I deactivated the views generation, and migrated the tables and launched my test server using php artisan serve.
Then I try using postman to post the following json to the /register route provided by Fortify.
Postman has been setup with the following headers:
Content-Type: application/json
Accept: application/json
{
"name": "test1",
"email": "test1#example.com",
"password": "MyPassw0rd!",
"password_confirmation": "MyPassw0rd!"
}
The response returned by the request was an error 419 CSRF Token mismatch, which I understand since Laravel enforce the use of CSRF token.
Therefor I tried to add the /register route to the except array inside the middleware VerifyCsrfToken and tried again and this time I got a 201 created response.
From my understanding since the /register route exists within the web guard hence the CSRF token mechanic.
Since my final goal is to use Fortify with third-party frontend, how can achieve that without putting the route inside the except array (if possible)?
Is there a parameter to change inside config/fortify.php to allow this behavior?
Thanks for reading.
After playing I found the solution inside the middleware section of config/fortify.php
Replacing
middleware => ['web'],
with
middleware => ['api'],
Allow to user the register route without having to deactivate the CSRF on the route .

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.

Guzzle request crashes nginx

So im working on a SPA with Vue and want to make a axios request on the server (Laravel). The Cors problem between Vue and Larave has been taken care of.
This App should then send a Guzzle Request to another Application of ours (vanilla Php). When im doing this from the Laravel App with a console command everything works as expected.
However when im doing this in the browser (so from the SPA) everything works until the Laravel App sends the request to the plain PHP Server. Before entering the first line of php everything breaks and nginx crashes. The request is pending forever. I have to restart nginx to use it again.
When im doing the request to the plain Php App directly from the Vue SPA (axios) everything is working as it should. Only when there is a 3rd party involved everythings breaks down on the 2. request.
Maybe i need to send some Headers? Do have to tweak nginx? Something else?
Thanks in advance for your help.
Setup : laragon (nginx) on a windows machine
Vue
sendRequest(context, request){
return new Promise((resolve, reject) => {
axios.post('http://sampleurl.dev/api', {
'id': request.id,
})
.then(response => {
resolve(response)
})
.catch(error => reject(error))
}
Laravel
function create(Request $request){
$client = new Client();
$resp = $client->request('POST', 'http://sampleurl-plainphp.dev/api', [
'form_params' => [
'test' => 'test'
]
]);
return response()->json($resp, 200);
}

Redirection to login on user auth with Laravel 5.2

I have a Laravel 5.2 application running ok in the live server. It was also running ok in a Ubuntu 14.04 with Apache server.
Now I am using a MAC so I made a fresh installation of my App using the MAMP PRO application. All is runing ok in Frontend but when I try to login to the backend there is a redirection that doesn't allow me to be authenticated. The DB is exactly the same, so the user should be authenticated.
When I type user and password and the hit send the screen shows:
Redirecting to http://localhost/admin/dashboard
Then the screen refresh again and shows:
Redirecting to http://localhost/admin/auth/login
I have think that maybe it is related to the Session, but it is stablished to:
'driver' => env('SESSION_DRIVER', 'file'),
So I do not know why this can be a reason. Any idea?
UPDATE - I include a summary of routes.php
This is my routes.php file (chunks of it)
// Admin area
Route::get('admin', function () {
return redirect('/admin/dashboard');
});
Route::group([
'namespace' => 'App\Http\Controllers\Admin',
'middleware' => 'auth.admin',
], function () {
Route::get('admin/dashboard' , 'AdminController#index');
});
Route::get('admin/auth/login', 'App\Http\Controllers\Admin\Auth\AuthController#login');
It sounds like your routes aren't in the web middleware. Make sure all the routes that require cookies or the session are defined like this:
Route::group(['middleware' => ['web']], function() {
Route::get('your-route-here', 'SomeController#method');
});
This is a new feature in Laravel 5.2.

Categories