CakePHP 3: Session was already started with Hybridauth 3 - php

I have a LoginController where I do my usual login operation with combination of an email address and a password associated with the account.
I have separated my Hybridauth related code into a separate controller named OauthController where I have all my Hybridauth magic and where my callback / endpoint resides.
In the OauthController I check if user's email from the specified provider is already registered, and in either case I try to login that user with $this->Auth->setUser(object).
Whenever, or whatever from the $this->Auth is called, I get a response stating:
Session was already started
I have browser through CakePHP 3 code and found the following statement in:
vendor/cakephp/cakephp/src/Network/Session.php (335)
public function start()
{
if ($this->_started) {
return true;
}
if ($this->_isCLI) {
$_SESSION = [];
$this->id('cli');
return $this->_started = true;
}
if (session_status() === \PHP_SESSION_ACTIVE) {
throw new RuntimeException('Session was already started');
}
...
And that's the point in code where that message is thrown at me.
Now, as I browsed through the Hybridauth code itself, I have found following in:
vendor/hybridauth/hybridauth/src/Storage/Session.php (46)
public function __construct()
{
if (session_id()) {
return;
}
if (headers_sent()) {
throw new RuntimeException('HTTP headers already sent to browser and Hybridauth won\'t be able to start/resume PHP session. To resolve this, session_start() must be called before outputing any data.');
}
if (! session_start()) {
throw new RuntimeException('PHP session failed to start.');
}
}
And both of them call session_start, one before the other, although CakePHP's part is blocking me.
I have tried removing !session_start() check from Hybridauth, but then Hybridauth doesn't know where to read out it's thingies it needs to read.
So, as a demonstrator, I am trying to achieve this in OauthController:
<?php
namespace App\Controller;
use Hybridauth\Hybridauth;
class OauthController extends AppController
{
public function callback($provider)
{
try {
$hybridauth = new Hybridauth($config);
// additional mystery code
$hybridauth->authenticate();
if($everything_okay) {
$this->Auth->setUser($userObject); // and this is the point of failure
return $this->redirect('/account'); // and this never happends... :(
}
}
}
}
Any help, ideas, insights on how to deal with this are all welcome!

Simply start the CakePHP session manually before using the Hybridauth library, so that it bails out at the session_id() check and picks up the existing session.
For example in your controller:
$this->getRequest()->getSession()->start();
// in CakePHP versions before 3.6/3.5
// $this->request->session()->start();

Related

Laravel Session Facade unexpected behaviour

In my Laravel 5.4 project I was trying to store a state token in my controller method like this..
use Illuminate\Support\Facades\Session ;
...
public function authorize()
{
Session::set('state', $client->getState());
A lot of code here...
header('Location: ' . $authorizationUrl);
exit;
}
I also tried using the helper function
session('state', $client->getState());
But no matter what I've tried the session would not be created or persist.
So I switched to using the Symfony component directly..
use Symfony\Component\HttpFoundation\Session\Session;
...
public function authorise()
{
$session = new Session();
$session->set('state', $client->getState());
...
}
Doing it this way works perfectly. Any explanation why the facade is not working?
As a reference if anyone else has an issue like this, the issue was being caused by a redirect, to an oauth url, before the function finishes, or a view was loaded etc. (i.e. the session gets stored at the end of the Laravel application "lifecycle".) This issue can manifest itself in any number of situations other than just a redirect, including using dd() or die()etc.
e.g. If your method is basically like this Sessions works fine.
public function myAwesomeMethod($params)
{
Session::put('theKey','theValue');
return view('theView'); //Session gets stored at this point.
}
However if your method looks like something like this you will have an issue.
public function myCoolMethod($authUrl)
{
Session::put('theKey','theValue');
header('Location: ' . $authUrl); //Session seems to be lost here.
exit;
}
The solution was simple but I missed it because of my unfamiliarity with the Laravel sessions. In the last example simply add the save() method to the Sessions class (if using the Facade) like in the following.
public function myCoolMethod($authUrl)
{
Session::put('theKey','theValue');
Session::save();// Session gets stored immediately
header('Location: ' . $authUrl);
exit;
}

Disabling the Codeigniter’s cache for logged in users

I'm using codeigniter cache on my personal CMS. The problem is, i don't want to show cached pages if the user it's logged on administration.
Saw this tutorial on google:
http://www.badpenguin.org/codeigniter-cache-disable
class MY_Output extends CI_Output {
function _display_cache(&$CFG, &$URI)
{
/* Simple Test for Ip Address */
if ($_SERVER['REMOTE_ADDR'] == NOCACHE_IP )
{
return FALSE;
}
/* Simple Test for a cookie value */
if ( (isset($_COOKIE['nocache'])) && ( $_COOKIE['nocache'] > 0 ) )
{
return FALSE;
}
/* Call the parent function */
return parent::_display_cache($CFG,$URI);
}
}
The problem it's that the session it's on database (ci_sessions), and i can't access it inside MY_Output.
using:
$CI =& get_instance();
$CI->session->userdata('userID')
give me:
Class 'CI_Controller' not found in
As output runs before controller, and session Needs CIcontroller, the only Thing i can think of its disable session storage on database and the encription, and i don't want do that rs.
Someone can give me some light on this? i still can't find the solution to this!
Thanks!
Try this:
#$SESS = & load_class('Session', 'libraries/Session');
The # is there to prevent it from whining about "session already started". Do note: this is for CI3. The code for the original Output class states (lines 407-409):
// Note: We use load_class() because we can't use $CI =& get_instance()
// since this function is sometimes called by the caching mechanism,
// which happens before the CI super object is available.

ZF2 routing and redirect function in controller

The following problem I am facing, error look likes this;
An error occurred
An error occurred during execution; please try again later.
Additional information:
Zend\Mvc\Exception\DomainException
File: .../vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Url.php:63
Message:
Url plugin requires that controller event compose a router; none found
I never faced this problem while I am trying to redirect from my controller. Lets say I implement the following function for redirection in my controller, which produces the error above;
public function __construct()
{
# Get user identity
$auth = new AuthenticationService();
if ($auth->hasIdentity()) {
$this->identity = $auth->getIdentity();
} else {
$this->redirect()->toRoute('admin/login');
}
}
The routing does exist as I can reach site.com/admin/login/ .. login is a child of admin so notation must be good. I am wondering what's going wrong and how to fix this issue or even, where to look for it would be a great starting point as well.
Thanks!
If you look at the error looks like you cant use the redirect plugin during the constructions of controller.
Url plugin requires that controller event compose a router; none found
might better to put that code in the onDispatch function like this.
public function onDispatch(MvcEvent $e)
{
# Get user identity
$auth = new AuthenticationService();
if ($auth->hasIdentity()) {
$this->identity = $auth->getIdentity();
} else {
return $this->redirect()->toRoute('admin/login');
}
return parent::onDispatch($e);
}
remember to return the redirect as otherwise the action will still be executed.

getUser() always return 0 in Codeigniter

I started to create a small application using codeigniter framework
and i have dowloaded Facebook connect from github after creating my application inside facebook, at this moment all work alright my only problem is getUser() always return 0
i have create a facebook.php inside application/config/
alse i have extracting facebook.php & base_facebook.php inside application/libraries/
this is my code
class Welcome extends CI_Controller {
private $data = array();
public function index() {
$this->data['loginUrl'] = $this->facebook->getLoginUrl();
$this->data['userId'] = $this->facebook->getUser();
$this->load->view('welcome_message', $this->data);
}
}
in autoload
i have :
$autoload['libraries'] = array('database','session','facebook');
so why getUser() return 0 and how can i fix this problem
thx
on base_facebook.php, find the makeRequest() method, and, inside the function, find this line:
$opts = self::$CURL_OPTS;
Immediately following it, add:
$opts[CURLOPT_SSL_VERIFYPEER] = false;
or read from here
It does this, sometimes. I've never worked out why, but there is a simple solution that I now always follow.
As opposed to asking for getUser, ask for api(/me) wrapped in a try catch block. If this fails, user is not logged in/token is invalid. If it works the user is logged in, and you get the user id from the resultant array.
You're probably saving a call, as you'll ask for /me anyway. Just remember the try catch for error trapping!

Codeigniter redirect does not work in IE9

I am having big time trouble with Codeigniter and Internet Explorer.
Please take a look at the sample page
It is something very simple afflicting me the last couple of days.
By pressing the login-button I do nothing more but calling a function start()
public function start()
{
setcookie('loginstatus', TRUE, time()+7200); // setting a cookie
redirect('stream', 'location'); // redirecting to the index controller
}
In the index-function I do the following:
public function index()
{
if ($this->isuserloggedin() == TRUE)
{
echo "The user is already logged in";
$this->load->view("v_stream_start");
} else {
echo "The user still has to login";
$this->load->view("v_stream_login");
}
}
Here's the userisloggedin() method where I check for an existing cookie:
public function isuserloggedin() {
if (isset($_COOKIE['loginstatus'])) {
return TRUE;
} else {
return FALSE;
}
}
Please check IE vs. FF/Safari/Chrome. It is working in all browsers exept IE and I have no clue why.
Everything runs as expected until I call the redirect() method - after that IE somehow can’t retreive the cookie while all other browsers can.
I already tried changing ci_session to ci_session and also checked the accurate server time.
Thanks so much for any kind of help.
Have you tried using the $this->input->cookie() methods instead of setting it raw through php?
http://codeigniter.com/user_guide/libraries/input.html
Okay the soultion seems to be, that you can not redirect within your own controller to your index-function and retreive the cookies there with Internet Explorer. When you redirect to another method within that controller it is working => redirect('controllername/methodname);

Categories