Hello guys I'm using Laravel 9 with NextJs to build a ecommerce app with a shopping cart.
However when I list products I try to add them to session in Laravel, the value is always null.
Here is my NextJs code:
const addToCart = async (productId: number) => {
console.log(productId)
try {
// add product to cart
const rawResponse = await axios.post(`http://localhost:3001/product/add-to-cart/${productId}`);
// get product data from session
const cartData = await axios.get(`http://localhost:3001/products/cart`);
} catch (e) {
}
}
I'm just passing poductId, and making sure Laravel saves that product in the session
Here is how my Laravel code looks like I have 2 routes in web.php : first for adding product to session, and second to list products
Route::post('product/add-to-cart/{id}', [ProductController::class, 'addProductToCart']);
Route::get('products/cart', [ProductController::class, 'getProductsInCart']);
ProductController
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Product;
class ProductController extends Controller {
public function addProductToCart(Request $request, $id) {
$product = Product::findOrFail($id);
$cart = session()->get('cart', []);
if(isset($cart[$id])) {
$cart[$id]['quantity']++;
} else {
$cart[$id] = [
"productId"=> $product->id,
"name" => $product->name,
"quantity" => 1,
"price" => $product->price,
];
}
session()->put('cart', $cart);
return response()->json(['success' => 'success'], 200);
}
public function getProductsInCart(Request $request) {
$cart = session()->get('cart');
var_dump($cart);
return $cart;
}
}
I have allowed CORS request
here is how my Kernel.php looks like
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array<int, class-string|string>
*/
protected $middleware = [
\Fruitcake\Cors\HandleCors::class,
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
];
/**
* The application's route middleware groups.
*
* #var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// \App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array<string, class-string|string>
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
'isAdmin' => \App\Http\Middleware\isAdmin::class,
];
}
But for some reason in second route, when I log session it returns null
$cart = session()->get('cart');
var_dump($cart); // is null
Does anyone know what could be potential problem?
Related
I try to create an application using laravel, when I create the login page after having entered the information contained in the database I have this error:
here my code for login controller:
namespace App\Http\Controllers;
use App\Models\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use illuminate\Session\Middleware\StartSession;
class AuthController extends Controller
{
public function login(Request $request)
{
$validator = Validator::make($request->all(), [
'email' => 'required|email',
'password' => 'required',
]);
if ($validator->fails()) {
return redirect()->back()->withErrors($validator)->withInput();
}
$user = User::getByEmail($request->email);
if ($user && Hash::check($request->password, $user->password)) {
Auth::login($user);
return redirect()->intended('/home');
} else {
return redirect()->back()->withErrors(['email' => 'The provided credentials do not match our records.'])->withInput();
}
}
}
here my web.php:
use Illuminate\Auth\Events\Login;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Facades\Session;
use App\Http\Controllers\AuthController;
use App\Http\Controllers\Auth\LoginController;
use Illuminate\Support\Facades\DB;
use Illuminate\Session\Middleware\StartSession;
use Illuminate\View\Middleware\ShareErrorsFromSession;
Route::get('/', function () {
return view('welcome');
});
Route::group(['middleware' => ['web']], function () {
Route::get('/login', function () {
return view('login');
});
});
Session::start();
Route::post('/login', [App\Http\Controllers\AuthController::class, 'login'])->name('login');
Route::get('/client_items', 'App\Http\Controllers\ClientController#showClientItems')->middleware('auth');
Route::get('/listeitems/{siteId}/{operatorId}', 'ItemController#getItemsBySiteAndOperator');
Route::get('/hors-ligne', function () {
$pdo = DB::connection()->getPdo();
$stmt = $pdo->query('SELECT * FROM item');
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return view('hors-ligne', ['rows' => $rows]);
});
I tried everything it's been 7 days since I was stuck on it
Edit:
here is my kernel.php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array<int, class-string|string>
*/
protected $middleware = [
// \App\Http\Middleware\TrustHosts::class,
\App\Http\Middleware\TrustProxies::class,
\Illuminate\Http\Middleware\HandleCors::class,
\App\Http\Middleware\PreventRequestsDuringMaintenance::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
];
/**
* The application's route middleware groups.
*
* #var array<string, array<int, class-string|string>>
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
// \Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
],
'api-session' =>[
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
]
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array<string, class-string|string>
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'auth.session' => \Illuminate\Session\Middleware\AuthenticateSession::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class,
'signed' => \App\Http\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
}
and the error:
I cannot get my Laravel setup to find my authenticated user in my StripeController. I am trying to set up a Stripe webhook to perform an action once a successful payment has been made.
I have done lots of reading on similar issues but after trying fixes I've read, most of them contiue to return null.
My latest attempt is below which returns status code 419 and Page Expired.
StripeController.php
class StripeController extends Controller
{
public function __construct(){
\Stripe\Stripe::setApiKey(env('STRIPE_SECRET'));
}
public function paymentSuccess()
{
// The commented code fetches the first User OK but I want the logged in user.
// $userDetails = User::first();
// $userDetails->is_subscribed = 1;
// $userDetails->save();
//This always returns null, as does any other user() command.
return Auth::user();
}
public function createSession(Request $request)
{
$session = \Stripe\Checkout\Session::create([
"success_url" => "https://www.mymarketingwizard.io/#/dashboard",
"cancel_url" => "https://example.com/cancel",
"payment_method_types" => ["card"],
"line_items" => [[
"name" => "Lifetime Access",
"description" => "Lifetime Access",
"amount" => 15000,
"currency" => "gbp",
"quantity" => 1
]]
]);
return $session;
}
My login script:
AuthController.php
public function login(Request $request)
{
$request->validate([
'email' => 'required|string|email',
'password' => 'required|string'
]);
$credentials = request(['email', 'password']);
$credentials['active'] = 1;
$credentials['deleted_at'] = null;
if(!Auth::attempt($credentials))
return response()->json(['error' => 'unauthorized'],404);
$user = $request->user();
$tokenResult = $user->createToken('Personal Access Token');
$token = $tokenResult->token;
if ($request->remember_me)
$token->expires_at = Carbon::now()->addWeeks(1);
$token->save();
return response()->json([
'access_token' => $tokenResult->accessToken,
'token_type' => 'Bearer',
'expires_at' => Carbon::parse(
$tokenResult->token->expires_at
)->toDateTimeString()
]);
}
I have read lots of other similar questions about this issue, many pointing towards a 'middleware' => 'web' must be used where you want to access Auth::user so this is my latest attempt:
api.php
Route::group(['prefix' => '/'], function () {
Route::group(['middleware' => 'web'], function () {
Route::auth();
Route::post('paymentSuccess','StripeController#paymentSuccess'); // Route I'm a hitting via Stripe
});
Route::post('login', 'AuthController#login');
Route::post('send-token', 'AuthController#sendToken');
Route::post('validate-token', 'AuthController#validateToken');
Route::post('reset-password', 'AuthController#resetPassword');
Route::group(['middleware' => 'auth:api'], function() {
Route::post('session','StripeController#createSession');
I have also read other solutions about moving the 'web' classes out of middlewareGroups and into global middleware in the Kernel.php but that also did't work for me.
Kernel.php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
\Spatie\Cors\Cors::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* #var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}
Payment.vue
This is my Vue Component which creates the Stripe session when the component is first created. When the user clicks the proceed to checkout button, the method is executed.
methods: {
checkout() {
stripe
.redirectToCheckout({
sessionId: this.sessionId.id
})
.then(result => {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
})
}
},
created() {
api
.post('/session')
.then(response => {
this.sessionId = response.data
})
.catch(error => {
})
}
My goal is to update my Users' table to say that the user who processed the payment is now subscribed.
This usually happens when CSRF check failed. Add your webhook endpoint as an exception in VerifyCsrfToken middleware:
protected $except = [
'paymentSuccess',
];
Alright so I got this locale system with a middleware, the issue is that when I enter language "hu"it doesnt set it the first time, it usualy works only the 2nd time I do it...
web.php
Route::get('set_language/{locale}', function ($locale) {
Session::forget('my_locale');
session(['my_locale' => $locale]);
return Redirect::back();
});
Language.php inside HTTP/middleware
<?php namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Foundation\Application;
class Language {
public function __construct(Application $app, Request $request) {
$this->app = $app;
$this->request = $request;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$this->app->setLocale(session('my_locale', config('app.locale')));
return $next($request);
}
}
And of course I added it inside my Kernel.php on couple of spots that seemed correct
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\App\Http\Middleware\TrustProxies::class,
\App\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\Language::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\Language::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class,
];
/**
* The priority-sorted list of middleware.
*
* This forces non-global middleware to always be in the given order.
*
* #var array
*/
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\App\Http\Middleware\Language::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Illuminate\Auth\Middleware\Authorize::class,
];
}
EDIT:
I forgot to mention, but in the config/app.php I've set it this way
'locale' => 'rs',
'locales' => ['rs', 'hu'],
'fallback_locale' => 'rs',
'available_locale' => ['rs', 'hu'],
So now If I got to the localhost:8000/set_language/rs it works, but if I do localhost:8000/set_language/hu it works only after I do it twice.
I tried dumping the session key my_locale and it stays as "rs" until I do the set_language/hu twice
So how I do it?
Go to: localhost:8000/set_language/hu
Go again to: localhost:8000/set_language/hu
Now it works...
Why isnt it being set the first time around?
Just to add up, if you are testing this, try setting your locale to RS first and then try to set it to HU
I am building a laravel application where I have web and api routes.
I want to store sessions between my routes.
If i store as session without returning a view, it works fine.
But when i return a view my session no longer exists.
My web.php is as follows:
Route::get('/', 'ViewController#index');
Route::get('/check', 'ViewController#check');
My controller
public function index(Request $request)
{
$request->session()->put('test','123456');
$request->session()->save();
//echo $request->session()->get('test', 'default_value');
// return view('welcome'); //If I uncomment this the sessions are not working anymore.
}
public function check(Request $request)
{
echo $request->session()->get('test', 'default_value');
var_dump($request->session()->all());
//return view('welcome');
}
Maybe it has something to do that i also store sessions in my api routes in the api controllers. My api.php:
Route::group(['middleware' => ['web']], function () {
//board
Route::get('/board/create', 'BoardController#create');
Route::post('board/{id}/guess', 'BoardController#guessWord');
Route::get('/board/set', 'BoardController#set');
Route::get('/board/get', 'BoardController#get');
//user
Route::get('/user', 'UserController#get');
Route::post('/user/create', 'UserController#create');
});
kernel.php
<?php
namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* These middleware are run during every request to your application.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
\App\Http\Middleware\TrimStrings::class,
\Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
\App\Http\Middleware\TrustProxies::class,
];
/**
* The application's route middleware groups.
*
* #var array
*/
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
/**
* The application's route middleware.
*
* These middleware may be assigned to groups or used individually.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
'can' => \Illuminate\Auth\Middleware\Authorize::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
}
Thanks!
From the docs api routes does not use StartSession middleware because session is only available in web group of middlewares
So store session only in web routes
When I call:
Auth::loginUsingId($user->id, true);
print_r(Auth::user());
...It's ok. But when I have this function after that:
return redirect('/');
Now in mydomain.com I called print_r(Auth::user()); and it return null;
Here is my Kernel.php
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* #var array
*/
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
];
/**
* The application's route middleware.
*
* #var array
*/
protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class,
'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'admin' => \App\Http\Middleware\AdminMiddlware::class
];
}
Laravel version: Laravel Framework version 5.1.46 (LTS)