Whenever I try to add a product to a wishlist I am redirected to a login page where I enter my credentials and after that it keeps reloading and this error appears.
Thereafter, when I return to home page and refresh I am logged in. But when I try to access a page directly which requires login, it works perfectly fine. This error has been appearing for sometime now, it was previously working fine.
routes:
Auth::routes();
Route::group(['middleware'=>'auth'],function (){
Route::get('/checkout','PageController@checkout')->name('checkout');
Route::post('/coupon','PageController@coupon')->name('coupon.check');
Route::post('/order', 'OrderController@store')->name('order.store');
Route::post('/orderinfo', 'OrderInfoController@store')->name('orderinfo.store');
Route::get('/invoice/{order}','PageController@invoice')->name('invoice');
Route::resource('/profile', 'ProfileController');
Route::get('/wishlist', 'WishlistController@index')->name('wishlist.index');
Route::get('/wishlist/{product_id}/remove', 'WishlistController@remove')->name('wishlist.remove');
Route::get('/wishlist/{product_id}', 'WishlistController@quick')->name('wishlist.quick');
Route::resource('/review', 'ReviewController');
Route::get('/orders', 'PageController@order')->name('orders');
Route::group(['middleware'=>'admin'],function () {
Route::resource('/admin/products', 'ProductController');
Route::resource('/admin/categories', 'CategoryController');
Route::resource('/admin/subcategories', 'SubcategoryController');
Route::resource('/admin/coupons', 'CouponController');
Route::resource('/admin/taxes', 'TaxController');
Route::resource('/admin/discounts', 'DiscountController');
Route::get('/admin/index', 'PageController@admin')->name('admin.index');
Route::post('/admin/ajax/category', 'PageController@ajax')->name('ajax.category');
Route::resource('/admin/users', 'UserController');
Route::resource('/admin/tracks', 'TrackController');
Route::get('/order', 'OrderController@index')->name('order.index');
Route::get('/order/{order}', 'OrderController@show')->name('order.show');
});
});
Route::get('/product/{product}','PageController@product')->name('product.view');
Route::get('/','PageController@index')->name('index');
Route::get('/about-us','PageController@about_us')->name('about_us');
Route::resource('/contact-us','ContactController');
Route::get('/shop','PageController@shop')->name('shop');
Route::get('/home', 'HomeController@index')->name('home');
Route::post('/cart', 'CartController@add')->name('cart.add');
Route::get('/cart{product}', 'CartController@quick')->name('cart.quick');
Route::get('/cart/show', 'CartController@show')->name('cart.show');
Route::patch('/cart/{product_id}', 'CartController@update')->name('cart.update');
Route::get('/cart/{product}/remove', 'CartController@remove')->name('cart.remove');
Route::get('/shop/filter/{subcategory_id}','PageController@filter')->name('filter.product');
Route::get('/shop/category/{category}','PageController@shop_2')->name('filter.categories');
Login Controller:
<?php
namespace App\Http\Controllers\Auth;
use App\Category;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo;
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
public function redirectTo()
{
}
public function showLoginForm()
{
$categories = Category::all();
$cart_items = session()->get('cart');
$sub_total = 0;
if (!empty($cart_items)) {
foreach ($cart_items as $item) {
$sub_total = ($item['price'] * $item['quantity']) + $sub_total;
}
}
return view('login', ['cart_items' => $cart_items, 'sub_total' => $sub_total,'categories'=>$categories]);
}
}
This is how I am sending get request and which gives error after login:
<a class="add-wishlist" title="wishlist" href="{{route('wishlist.quick',$product->id)}}"><i class="fa fa-heart"></i></a>
Wishlist Controller:
<?php
namespace App\Http\Controllers;
use App\Category;
use App\Helpers\helper;
use App\Product;
use App\Wishlist;
use Illuminate\Http\Request;
class WishlistController extends Controller
{
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//
$categories= Category::all();
$cart_items = helper::cart_data();
$sub_total = helper::sub_total($cart_items);
$user_id = auth()->user()->id;
$wishlist = Wishlist::all()->where('user_id', '=', $user_id);
$products = [];
foreach ($wishlist as $list) {
$products[] = Product::find($list->product_id);
}
return view('wishlist', ['wishlist' => $wishlist, 'products' => $products,'sub_total'=>$sub_total,'categories'=>$categories,'cart_items'=>$cart_items]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//
$user_id = auth()->user()->id;
$check = Wishlist::all()->where('user_id', $user_id)->where('product_id', $request['product_id']);
if ($check->isEmpty()) {
Wishlist::create([
'user_id' => $user_id,
'product_id' => $request['product_id']
]);
}
return redirect()->back();
}
/**
* Display the specified resource.
*
* @param \App\Wishlist $wishlist
* @return \Illuminate\Http\Response
*/
public function show(Wishlist $wishlist)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param \App\Wishlist $wishlist
* @return \Illuminate\Http\Response
*/
public function edit(Wishlist $wishlist)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param \App\Wishlist $wishlist
* @return \Illuminate\Http\Response
*/
public function update(Request $request, Wishlist $wishlist)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param \App\Wishlist $wishlist
* @return \Illuminate\Http\Response
*/
public function remove(Request $request)
{
//
$user_id = auth()->user()->id;
Wishlist::where('user_id', $user_id)->where('product_id', $request['product_id'])->delete();
return redirect()->back();
}
public function quick($product_id)
{
//
$user_id = auth()->user()->id;
$check = Wishlist::all()->where('user_id', $user_id)->where('product_id', $product_id);
if ($check->isEmpty()) {
Wishlist::create([
'user_id' => $user_id,
'product_id' => $product_id
]);
}
return redirect()->back();
}
}
Firstly, 419 error indicate an expired session. I notice you are using the session helper method session()
inside showLoginForm()
. You should be aware that if a user is logged out or his/her session expires then that user cannot access the data stored in that session as it will be wiped clean. Trying to access session data this way through showLoginForm
is counter-intuitive as the user will most likely have been logged out or had an expired session before accessing the login form - except for the case where the user is accessing the login form for the first time. This could be a possible cause of the 419 errors.
You can remove the piece of code where you are trying to access the session data to any of your several controllers that require authentication. Then, you are sure that the user has a valid session before accessing session data.
However, to redirect users after a successful login Laravel uses either the $redirectTo
variable or redirectTo()
method of the LoginController. If the method is defined, it overrides the variable and if not, the variable is used.
From your LoginController, none of them is defined. Usually, the variable is set to redirect to the homepage - $redirectTo = '/home'
. However, to meet your requirement of redirecting to the page that required the login, you must use the redirectTo()
method.
You can achieve this by using the helper method url()->previous()
within LoginController.php
like this:
public static $previous;
public function showLoginForm() {
self::$previous = url()->previous();
// continue with your code.
}
public function redirectTo()
{
return self::$previous;
}
notice that I store the previous url when i first show the login form. after a successful login, this url should be available for me to redirect to.
UPDATE 1:
The problem route
Route::get('/cart{product}', 'CartController@quick')->name('cart.quick');
has a problem. You are missing a forward slash after /cart
. You should notice this issue when you look at the generated url in the link. The correct form should be
Route::get('/cart/{product}', 'CartController@quick')->name('cart.quick');
UPDATE 2:
Since the route wishlist.quick
is going through the auth
middleware, do not use redirect()->back()
for going back to the same page after user action with that route.
This is because, with the auth
middleware in place, redirect()->back()
is not always pointing to same location.
For instance, an unauthenticated user accessing the wishlist.quick
route will be redirected to the login page. If login is successful the request continues to wishlist.quick
route. Now, try to guess where the redirect()->back()
inside WishlistController@quick
is pointing to. Right! Surprisingly, it is pointing to the login page. So now the authenticated user completes his/her request with WishlistController@quick
and is directed to the login page again. The login controller detects the user is authenticated and redirects the user to wherever he/she is coming from - WishlistController@quick
. Again, there is redirect()->back()
sending the user back again to the login page. You see the infinite redirect loop clearly in this funny scenario.
SOLUTION:
Change the line
return redirect()->back();
to
return $this->index();
Since WishlistController@quick
doesn't return a view of its own, WishlistController@index
is the best place to return to. Infact, you have to make this change for all routes that pass through a middleware and redirects the user back.
In other words, do not use redirect()->back()
in a route that goes through middleware, if you really mean to go back to the same page.