laravel: redirect to same controller with query parameters when cookie exists - laravel

First, here's a little background on what I'm trying to accomplish:
I'm building a SaaS app, and on the marketing site, the user can select a plan which will direct them to the registration page. I'm using a very similar flow to Mailchimp.
Once they register, they have to verify their email. Once they verify their email, they "complete" their account with information like address, city, etc.
Then, they're taken to the paywall.
My problem
I need a way of remembering which plan they wanted from the marketing site when they land on the paywall. To do this I was going to set a cookie.
If a cookie exists of a certain value, I want to redirect to that same route, but add a query parameter such as ?plan=free
Here is my controller function tied to the route route('paywall')
/**
* Returns all the data needed for the paywall
*/
public function paywall() {
if ($plan_intent = Cookie::get('plan-intent')) {
return redirect()->route('paywall', ['plan' => $plan_intent]);
}
$account = auth()->user()->accounts->first();
$billingAccount = $account->billingAccount;
$contactDetails = $account->contactDetails();
return view('account.paywall', [
'plans' => Plan::all(),
'intent' => $account->createSetupIntent(),
'currentPlan' => $account->plan,
'contactDetails' => $contactDetails,
'billingAccount' => $billingAccount,
'states' => State::all()
]);
}
The code above is causing a redirection loop: (site name) redirected you too many times.
How can I conditionally add query parameters to the same route and redirect to the same route?

I had to do a check to see if the param was there. That's why the redirect loop was happening:
if ($plan_intent = Cookie::get('plan-intent') && !request()->input('plan')) {
return redirect()->route('paywall', ['plan' => $plan_intent]);
}

Related

How can I add ask username and password feature to only one of my laravel routes?

I have created a few forms in laravel. I want to restrict access to one of them only to a specific user.
I want to create a user and password myself.
This is my routes excerpt. This is the route I want to protect from access
Route::get('/tabledata_id_title', 'KedivimController#appearanceiddata');
This is my controller excerpt:
public function appearanceiddata()
{
//$magic = DB::table('prog_title')->select('pr_id', 'pr_title')->get();
$magic = DB::table('prog_title')->select('pr_id', 'pr_title')-> where('pr_index', '=', 1)->get();
return view ('takealook', ['magical' => $magic]);
}
This is a short fix for your problem.
public function appearanceiddata()
{
if (!Auth::guard('web')->check()) //check if someone is logged in
{
//redirect to login page.
}
else {
/*Check if the logged in user is your desired user.
Maybe try matching the logged in id with your desired id.
If you find that a user is logged in but they are not your desired user
then you may redirect them in some other place or show them a message. */
}
//$magic = DB::table('prog_title')->select('pr_id', 'pr_title')->get();
$magic = DB::table('prog_title')->select('pr_id', 'pr_title')-> where('pr_index', '=', 1)->get();
return view ('takealook', ['magical' => $magic]);
}
However, this practice is ok if you have one or two restricted field. But if you have more than that then you should read about middleware.

Shopify API returns empty cart

Using this API: https://help.shopify.com/en/themes/development/getting-started/using-ajax-api#add-to-cart
From my messenger bot I call cart/add.js multiple times with the variant id and quantity and it returns a success message, but I call cart.js to retrieve the items, the cart is always empty.
I'm adding items to the cart like this:
$cartAPI = 'https://'.$shopKey.':'.$shopSecret.'#'.$shopUrl.'/cart/add.js';
$request = $client->request('POST', $cartAPI, [
'form_params' => [
'id' => (int) $productID,
'quantity' => 1
]
]);
And retrieving cart like this:
$cartAPI = 'https://'.$shopKey.':'.$shopSecret.'#'.$shopUrl.'/cart.js';
$request = $client->get($cartAPI);
I tried to include cookies in the Guzzle call like so
$this->client = new Client(['cookies' => true]); and both calls use the same client instance, but it still returns an empty cart.
I don't use CloudFlare or any Caching mechanism for this.
What am I doing wrong?
You are doing something wrong. Why would you make a call to Shopify with a key and a secret? Are you not selling yourself a little short here? I mean if I examined your source code, and saw a key and secret, I would be able to use that to do anything I want. Is that the goal here? Allowing anyone on the Internet to make you look silly? Shopify has a button you can place anywhere to add products to a cart. You can use that. It is secure.
Solution i figured out here for anyone having the same issue. I needed to use the cart cookie. Ended up doing something like:
$cartCookie = Cache::tags(['user:' .$userId, 'cookies'])->get('cart');
if (!$cartCookie) {
$client = new Client(['cookies' => true]);
} else {
$cookieJar = CookieJar::fromArray([
'cart' => $cartCookie,
], conf('shop.url'));
$client = new Client(['cookies' => $cookieJar]);
}
Cookie is stored in the cache the first time the user adds an item to the cart and used for recurrent adds. I had to put it in Cache since I'm building a chatbot but you can just use cookies from your browser.

remember me for laravel5.2

Hello guys I want to make the remember me checkbox and I want to save the user info into cookies so next time when try to login he find the user name and password in their fields I try to use :
$rememberMe = false;
if(isset($req->remember_me)) {
$rememberMe = true;
}
if(Sentinel::authenticate($req->all(), $rememberMe)) {
$slug = Sentinel::getUser()->roles()->first()->slug();
}
The cookies was set, I see it in the chrome settings but it does not do as I expect
I'm using laravel 5.2
You can use Cookies
cookie, is a small piece of data sent from a website and stored in a user's web browser while the user is browsing that website. Every time the user loads the website, the browser sends the cookie back to the server to notify the website of the user's previous activity
To create:
$response->withCookie(Cookie::make('name', 'value', $minutes));
To retrieve
$value = Cookie::get('name');
Your question is not to remember the user login.. The question is how to fill the inputs based on saved auth information. You can do that if you print the authentication values in the input value attribute while loading the page.
larval Cookies Docs
Also Laravel has it's own implementation of "Remember Me"
if (Auth::attempt(array('email' => $email, 'password' => $password), true))
{
// The user is being remembered...
}
if (Auth::viaRemember())
{
//
}
More information about https://laravel.com/docs/5.4/authentication#remembering-users
There is two main thing need to taken care:
1) You must pass a bool value as second parameter to the method, make sure you cast it before passing it to the method. - In your code, it's perfect
$credentials = $req->only('LOGINNAME', 'PASSNAME')
if(Sentinel::authenticate($credentials , $req->has('remember_me'))){
//Other stuff
}
2) you can verify it works by ensuring a cookie is set with the key cartalyst_sentinel?
So first change as per 1) option and then check the 2) option, may be this is your answer.

Pass variable from middleware to view via controller in Laravel 5.2

Hi I am trying to do the following in Laravel 5.2.
Summary: Pass some variables from middleware to view, via controller
Detailed: When a client is logged in, no matter what route they want, we need to check if they have completed all "setup steps" (each step refers to a different route, e.g. one could be company info, another could be product settings, etc). If they have completed all setup steps, then let them proceed to their chosen route, otherwise we redirect to the appropriate "setup steps" route, whichever one they haven't completed yet.
All client controllers run the same middleware, called NonSuperAdmin. I would like to put the checking of "setup steps" in this middleware, and redirect from there as appropriate. If client is redirected to a setup route by this middleware, we need the "incompleteSetupTasks" collection to be passed on to the relevant view, via the appropriate setup steps controller method.
Is this possible? Any help is much appreciated.
In the middleware use session handler
if($condition === true){
$data = [ //your content ];
Session::flash('your_key', $data);
}
next($request);
This data will also be available in your controller and in view
This is how you can access data in controller
public function yourControllerAction($request)
{
$somevariable = Session::get('your_key');
$viewdata = [
'content' => $somevariable
]
return view('yourview', $viewdata);
}
Or directly access the session data in view
//inblade
<p>
Your html content
#foreach(Session::get('your_key' as $data)
//your stuff
#endif
</p>
May be use Laravel Session to store and read values?
You can pass your setup steps to get or post parameters and check in routes with middleware if these parameters are empty:
Route::get('post/{setup1?}/{setup2?}', ['middleware' => 'role:admin', function ($setup1, $setup2) {
if(empty($setup1) and empty($setup2)){
// do smth
} else {
// redirect
}
}]);
Question marks mean, that they are optional parameters. Hope it was helpful.

Magento - Customer Not Logged in After Redirect From External Page

I'm having a lot of trouble getting a customer to stay logged in after I have created a new account. I'm creating them an account and adding products to a cart from an external site, and then sending them to Magento store. What I want to have happen is:
A customer goes to a signup page and enters relevant information.
They go to a new page where they can choose to add free samples to their cart.
After picking samples. their account is created and they are redirected to the Magento store with the samples in their cart.
The problem I'm having is between steps 2 and 3. I create an account using the Magento's SOAP API with the following:
$customerInfo = array('firstname' => $custFirstname, 'lastname' => $custLastname, 'email' => $email, 'password_hash' => md5( $new_password ), 'store_id' => 34, 'website_id' => 25,'group_id' => 9);
// Call API method customer.create
$newCustomerId = $client->call( $session, 'customer.create', array( $customerInfo ) );
I then return their customer ID, which I pass to another function which actually logs them in and adds products to their cart:
public static function _addSamplesToCart($customer_id, $sample_one, $sample_two, $sample_three){
Mage::getSingleton("core/session", array("name" => "frontend"));
$customerSession = Mage::getSingleton('customer/session', array("name" => "frontend"));
$customerSession->init("customer_bn_us");
$customerSession->loginById($customer_id);
$cart = Mage::getSingleton('checkout/cart');
$cart->addProductsByIds($idArray);
$cart->save();
$cart->getCheckoutSession()->setCartWasUpdated(true);
}
These functions are actually called from AJAX post requests, so when I get a successful return value from _addSamplesToCart, I do a simple javascript redirect (window.location ="http://www.myhostname.net/welcome") and it correctly takes me there, but I'm not logged in.
I've been looking around all afternoon and trying a few different things and nothing has worked. I've also tried doing a hidden form submit to /customer/account/loginPost and it still doesn't work. I have verified that it's correctly creating an account in Magento. My only hunch is that I'm doing this with a mix of AJAX and PHP so somehow the cookies or sessions are getting mixed up?
If you are trying to login from an hostname different from the one used by the Magento store, it cannot work. You can verify this by checking if a frontend cookie is created after the AJAX call.
I suggest you to create a new controller in Magento that receives the id of the customer just created and executes the code you wrote in your function:
www.myhostname.net/autologin/myaction/13 (where 13 is the id of the customer just created).
Obviously you should add something else to avoid security issues.

Resources