I'm new to Laravel and PHP in general, but familiar with Vue and SPA's. I know how to create authentication with Bcrypt, for example. However, I used Laravel to run php artisan make:auth and to create several different endpoints for the backend.
I was trying to convert my app into a SPA using Vue, however using routing with Vue causes issues with the routes defined in the web.php. For example, I have my web.php like this, with several different routes.
<?php
Route::get('/{vue_capture?}', function () {
return view('app');
})->where('vue_capture', '^(?!storage).*$');
Route::get('/', function () {
return view('app');
});
Route::resource('Videos', 'VideoController')->middleware('auth','isAdmin');
Route::resource('Categories', 'CategoriesController')->middleware('auth');
Route::get('/search', 'VideoController#search')->middleware('auth');
Auth::routes();
Route::get('/settings/account', 'AccountsController#edit')->middleware('auth');
Route::get('/auth', 'AccountsController#get');
Route::put('/settings/account', 'AccountsController#update')->middleware('auth');
However, I also have a routes.js to have vue-router handle the routing with the following :
import Home from './components/Home.vue'
import Videos from './components/Videos.vue'
import Categories from './components/Categories.vue'
export default{
mode: 'history',
routes: [
{
path:'/',
component:Home
},
{
path:'/Videos',
component:Videos
},
{
path:'/Categories',
component:Categories
},
{
path:'/login',
component:login
},
{
path:'/register',
component:register
},
{
path:'/logout',
component:logout
}
]
}
I understand that Vue is supposed to take over the routing if you use a SPA, but is there any way to use both? I can't find anything that addresses this issue but I can't believe that Laravel would make you choose to either use their built-in commands like php artisan make:auth or have to scrap all of that and do it all manually if you want a SPA with routing.
I've tried going through different CRUD turorials on using Laravel and or Vue.
I've tried directing all of the routes to Vue to have vue-router handle the routing.
I've tried not giving all routing to vue-router and retaining the back-end routes that I had in web.php
Other semi-related problem is my routes aren't even appearning as links using router-link . It just appears as normal text. But for now my priority is the routing issue.
You can combine both vue route and Laravel route. But for the best result, I advise you use vue router since you are building an spa.
remove
Route::get('/', function () {
return view('app');
});
put all the backend route before the route that point to your vue.
Route::resource('Videos', 'VideoController')->middleware('auth','isAdmin');
Route::resource('Categories', 'CategoriesController')->middleware('auth');
Route::get('/search', 'VideoController#search')->middleware('auth');
Auth::routes();
Route::get('/settings/account', 'AccountsController#edit')->middleware('auth');
Route::get('/auth', 'AccountsController#get');
Route::put('/settings/account', 'AccountsController#update')->middleware('auth');
Route::get('/{vue_capture?}', function () {
return view('app');
})->where('vue_capture', '^(?!storage).*$');
Also, verify that you don't have conflicting routes on your backend (run php artisan route:list to see your laravel route list) and vue routes. I hope this helps.
The accepted answer is perfect (I upvoted but I have no rep yet for it to count) and worked well for me but only under the condition if I also created 'dummy' vue components and imported them to work with the routes. Hope this helps!
import Login from './auth/Login'
import Register from './auth/Register'
import Logout from './auth/Logout'
{ path:'/login', component:Login },
{ path:'/register', component:Register },
{ path:'/logout', component:Logout },
You can just use this instead
Route::get('/{vue_capture?}', function () {
return view('app');
})->where('vue_capture', '^(?!storage).*$')->middleware('auth');
Related
Recently, I decided to use Laravel Sanctum to submit forms using Vue JS axios. I use Sanctum CSRF-Cookie to validate CSRF before every form submission.Unfortunately, after making this change and after setting up Laravel Sanctum now, all other forms my website such as sign out button (which is inside a form) doesn't work properly.For example, if I add one new person to database using axios to submit that form, after submission if I want to log out it redirects me to 419 page which says Page expired. In some sections of website, I used Vue JS components and Axios to submit forms without refreshing that page. I also don't use Sanctum SPA for authentication I just want to use it for CSRF validation for every form submission!There are some changes that I made and you may need to know but before that if there is any information that is missing in my question here, please let me know so I can update this thread as soon as possible. Also I found a similar question here but the guy who answered that question, hasn't used Vue JS as frontend and whatever he mentioned looked correct on my end and still, I cannot logout after submitting form using Vue JS component and Axios.If anybody here has any solution please answers below. Thank you.
I changed route middleware from API to WEB in RouteServiceProvider.php file like this:
public function boot() {
$this->configureRateLimiting();
$this->routes(function () {
Route::prefix('api')
->middleware('web')
->namespace($this->namespace)
->group(base_path('routes/api.php'));
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
});
}
I changed support_credentials to true in config\cors.php:
'paths' => ['api/*', 'sanctum/csrf-cookie'],
'supports_credentials' => true,
In config\sanctum.php file this is stateful value:
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:443,127.0.0.1:8000,::1',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
In .env file I don't actually know what should I set for subdomain because there is no subdomain. I just used 127.0.0.1 for SESSION_DOMAIN
SESSION_DRIVER=cookie
SESSION_LIFETIME=120
SESSION_DOMAIN=127.0.0.1
SANCTUM_STATEFUL_DOMAINS=127.0.0.1
SESSION_SECURE_COOKIE=true
Now in VUE JS component, I use this method to validate Sanctum CSRF before adding new contact:
async addNewContact ({commit})
{
await axios.get('/sanctum/csrf-cookie').then(() => {
axios.post(/api/new/contact/add, '', '')
.then(response => {
comit('newContactAlert', response.data.newContact)
})
.catch(err => {
console.log(err)
})
})
},
I have https://tenancyforlaravel.com/ installed in laravel to make multi-tenant and it works fine for the web routes.
My problem is that when I access my APIs then I get a 404 error in tenant domains.
tenancyforlaravel documentation: https://tenancyforlaravel.com/docs/v3/routes
It says that I must put all my APIs inside api.php file and wrap them in a Route group with this middleware so I put all my APIs inside api.php file and all my APIs as below:
Route::middleware('tenancy')->group(function () {
Route::name('api.')->namespace('Api')->group(function () {
Route::post('/login', 'AuthController#login')->name('login');
...
});
and when I access it using sub.local.test/api/login then I get 404 error.
Tested for tenancyforlaravel.com V3 and it works OK.
Route::middleware([
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class
])->prefix('api')->group(function () {
//
Route::name('api.')->namespace('App\Http\Controllers\Api')->group(function () {
Route::post('/login', 'AuthController#login')->name('login');
...
});
Put all your API routes inside api.php as below
use App\Http\Controllers\AuthController;
Route::group(['prefix' => '/{tenant}',
'middleware' => [InitializeTenancyByPath::class],],
function () {
Route::post('/login', [AuthController::class, 'login'])->name('login');
...
});
As you haven't mentioned your tenant identifier, I am using path as identifier, so using InitializeTenancyByPath middleware. Use whatever identifier middleware you want in place of that.
Access your API routes normally as you used to do, with your identifier. As this example uses path as identifier, the endpoint will look like:
sub.local.test/api/{tenant}/login
I have two projects running
One is front end
Other is backend
Frontend project is made in vue js and backend is made in laravel
I am trying to do a post request via axios but i get csrf token mismatch
I cant use the meta tag solution as they both are different projects
**Route i want to hit**
Route::group(['middleware' => 'auth'], function () {
Route::post('tasks', 'TaskController#store')->name('tasks.store');
});
**my axios call in my vue js project**
addTask:function()
{
this.displayError = false;
if($('.inputs').length > 0)
{
const config ={
onUploadProgress:function(progressEvent)
{
var percentCompleted = Math.round((progressEvent.loaded * 100)/progressEvent.total);
console.log(percentCompleted)
}
}
var form = new FormData();
form.append("title",this.title);
form.append("description",this.txtdesc);
form.append("status_id",this.status_id);
form.append("user_id",this.user_id);
axios.post("http://127.0.0.1:8020/tasks",form,config).then((res)=>{
console.log(res)
})
}else
{
this.displayError = true;
}
}
When i fire this function to send data to controller it gives csrf token mismatch error
If it was a laravel project i could've ha tried
adding {{csrf_field()}}
adding #csrf
adding csrf in meta
but how to do it in vue js
PS I have tried removing auth middleware but it returned the same error and
it will work if i place the route inside the cerifycsrftoken file in backend project
but i want to do it with csrf token
I placed my routes from web.php to api.php and added the prefix api which solved my csrf token mismatch problem
also if i place route url in verifyCsrfToken.php file it solves the issue without moving routes to api.php
I took route
Route::post('tasks', 'TaskController#store')->name('tasks.store');
from the web .php file and then i placed it in api.php file
Route::post('tasks', 'TaskController#store')->name('tasks.store');
also i didnt used auth middleware on them
Look at my code, Please.
web.php
Auth::routes();
//
Route::get('/', 'HomeController#index')->name('home');
Route::get('/findIDProvince', 'HomeController#findIDProvince')->name('findIDProvince');
Route::get('/markets', 'MarketController#index')->name('market');
Route::get('/market/{marketSlug}', 'MarketController#single');
Route::get('/category/{categorySlug}', 'CategoryController#single');
Route::match(['get', 'post'],'/cart/{market}',"MarketController#AddCard")->name('cart');
Route::get('/shopping-cart', 'MarketController#showCart')->name('cart');
Route::post('/comments', 'MarketController#comments')->name('comments');
Route::get('/{pageSlug}', 'PageController#contact')->name('contact');
Route::middleware('auth:web')->group(function () {
Route::post('/payment', 'PaymentController#payment')->name('payment');
Route::get('/payment/callback', 'PaymentController#callback')->name('payment.callback');
});
Route::prefix('ajax')->group(function() {
Route::post('/add-to-cart', 'AjaxController#add_to_cart');
Route::post('/remove-from-cart', 'AjaxController#remove_from_cart');
Route::post('/get-cart', 'AjaxController#get_cart');
Route::post('/increment-cart-item', 'AjaxController#increment_cart_item');
Route::post('/decrease-cart-item', 'AjaxController#decrease_cart_item');
Route::delete('/delete/{id}', 'AjaxController#delete');
});
Route::namespace('Admin')->middleware(['auth:web', 'checkAdmin'])->prefix('admin')->group(function (){
Route::get('dashboard', 'DashboardController#index')->name('dashboard');
Route::resource('slideShows', 'SlideShowController');
Route::resource('categories', 'CategoryController');
Route::resource('users', 'UserController');
Route::resource('markets', 'MarketController');
Route::resource('orders', 'OrderController');
Route::resource('pages', 'PageController');
Route::get('footers', 'FooterController#index')->name('footers.index');
Route::get('links', 'LinkController#index')->name('links.index');
Route::post('links/store', 'LinkController#store')->name('links.store');
Route::resource('address', 'AddressController');
Route::get('socials', 'SocialController#index')->name('socials.index');
Route::post('socials/store', 'SocialController#store')->name('socials.store');
Route::get('approved', 'CommentController#approved')->name('approved');
Route::get('unapproved', 'CommentController#unapproved')->name('unapproved');
Route::put('comment/update/{comment}', 'CommentController#update')->name('comment.update');
Route::delete('comment/destroy/{comment}', 'CommentController#destroy')->name('comment.destroy');
});
I have installed laravel 7 on my local server. When I run php artisan route:cache command then laravel returns the error:
I'm writing my project on Laravel. When I optimize the project, I have a problem :
Unable to prepare route [api/user] for serialization. Uses Closure.
I looked for any closures in web.php, but I didn't find anything.
Laravel can't cache routes, which use closures - https://github.com/laravel/framework/issues/22034
There is example user route in routes/api.php Just remove it and try again
need some help. I'm trying to fetch data from my db using axios. My backend is Laravel. I have a 200 status http request but it returns the whole html not the data I'm expecting.
Here is my code for route
Route::get('/home', 'PostController#ajaxCall');
Route::post('/home', 'PostController#store');
Route::get('/{any?}', function () {
return view('welcome');
});
Here is my code for Home.vue for Axios request
export default {
components: {addForm},
data () {
return{
posts:[]
}
},
created() {
axios.get('/home').then(response => this.posts = response.data);
}
}
For my controller
public function ajaxCall(){
return response(Post::all());
}
It looks like you get to the ajaxCall() method by using the route '/home', but with axios, you are hitting "/" which returns a view called Welcome. Maybe you need to change the path you use in axios to '/home'?
It might be late but maybe someone else is looking for the solution
I was also facing this in SPA using laravel and VUE.
Route::get('/{any}', 'SinglePageController#index')->where('any', '.*');
SPA has this route, so whenever you write any other get route your app will redirect you to the home page, to avoid this either move this route at the end of your web.php
or write your other routes in api.php file.
In my case i solved it by changing the GET method to POST method.
Try that. It might help