Magento - Customer Not Logged in After Redirect From External Page - session

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.

Related

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

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]);
}

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.

Registering users in Laravel as Admin

My current project is a school management system, and I'm using Laravel 5.6 (it's my first Laravel project). I've been trying to register a user from a small form I have inside the Administrator area of my application.
I've set up the routes for the Admin area (view names are not in English, sorry for that):
// Admin
Route::middleware(['auth'])->group(function () {
Route::view('/admin', 'profiles.admin.admin_gerencia_cadastro');
Route::view('/admin/gerencia/cadastro', 'profiles.admin.admin_gerencia_cadastro');
Route::post('/admin/gerencia/cadastro', 'RegController#store');
Route::view('/admin/gerencia/relatorios', 'profiles.admin.admin_gerencia_relatorios');
Route::view('/admin/ped/', 'profiles.admin.admin_ped');
});
The post route (third from the top) was supposed to handle registration of users and leads to RegController and the following method:
public function store()
{
$this->validate(request(), [
'name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
$user = User::create(request(['name', 'email', 'password']));
return redirect()->to('/admin/gerencia/cadastro');
}
It should store the new user data and redirect the Admin back to /admin/gerencia/cadastro. However, when the form is submitted data is not stored on the database and I'm redirected to the homepage instead. I've tried different things, consulted the documentation, but no success so far.
Any help will be much appreciated.
Edit:
Came here to post the form, as requested below, but I found my own mistake - a rookie one: the form action was wrong. Sorry guys, I'll close the question :)
Is your request reaching in store() method?
try to write
print_r($_REQUEST);exit;
on first line of method. If it's not reaching there, then put below route before all other routes of your route group:
Route::post('/admin/gerencia/cadastro', 'RegController#store');
check out this link for better understanding of routing in laravel.

Facebook losing logged in user with ajax

I am writing a Facebook app and have used the Facebook php SDK so it can be authorized server side. I can see this is working because after authorization when Facebook redirects back to my app, I have the following code in my index.php...
require_once 'facebook.php';
$facebook = new Facebook(array(
'appId' => '111111111111111',
'secret' => '11111111111111111111111111111111',
'cookie' => true
));
// Get User ID
$user = $facebook->getUser();
...and $user returns not null. So far, so good!
I have a link on my app that loads content via ajax when clicked. Here's the JS:
$.post('my_content.php', {
action: 'render'
}, function(res){
if (res.html.length) {
$('.content').html(res.html);
}
},'json');
The problem is, the my_content.php script seems to be losing the fact the user has logged in and authorized the app.
The code I run in the my_content.php script to check whether the user is logged in is the same as in index.php
require_once 'facebook.php';
$facebook = new Facebook(array(
'appId' => '111111111111111',
'secret' => '11111111111111111111111111111111',
'cookie' => true
));
// Get User ID
$user = $facebook->getUser();
This time though $user = $facebook->getUser() returns null.
Is there a way to check if the user is logged in and authorized when running a PHP script with an AJAX call?
Should I store something in a session variable in my index.php script?
EDIT
After even more reading, I'm wondering if I need to retrieve the access token using the JavaScript SDK and pass it to my_content.php. Does anyone know if that's the correct way to do it?
EDIT 2
Turns out the line giving me the problem isn't $user = $facebook->getUser():
It is this one
$user_profile = $facebook->api('/me');
This line fails with the error 'OAuthException: An active access token must be used to query information about the current user.'
Strangely though, if I do this
$access_token = $facebook->getAccessToken();
$user = $facebook->getUser();
echo $access_token;
echo $user;
I do indeed have an access token and a user ID, so it looks like it may well be the bug reported by CBroe - check comments below.

How to keep session data using Codeigniter and Tank Auth

I'm using Codeigniter and Tank Auth for a e-commerce website. I'm finding that if a customer puts items into the cart (using the Codeigniter built in cart class) and then registers on the site the session is lost along with their cart (I'm presuming it generates a new session for some reason instead of keeping the same session).
Has anyone come across this problem before? and is there a simply solution that I have overlooked.
Thanks
As far as the most recent code looks like, the only place the hole session is deleted is in the logout() function, Tank_auth.php Line 118:
https://github.com/ilkon/Tank-Auth/blob/master/application/libraries/Tank_auth.php#L118
The example usage of Tank Auth uses logout() in activate() and reset_email() - check your code for those methods. You could also change the Tank Auth logout function to something like this:
function logout($keep_session = false)
{
$this->delete_autologin();
// See http://codeigniter.com/forums/viewreply/662369/ as the reason for the next line
$this->ci->session->set_userdata(array('user_id' => '', 'username' => '', 'status' => ''));
if(!$keep_session)
$this->ci->session->sess_destroy();
}
... and the use it like this: $this->tankauth->logout(true);

Resources