Symfony2 A session had already been started - ignoring session_start() - session

I can't use Symfony2 session in my local server. I'm getting a "Notice: A session had already been started - ignoring session_start()" error.
Same script works fine in my production server.
I'm using Xampp with PHP 5.3.5 over Windows 7. Session auto_start is off in php.ini.
Any hint will be helpfull. Thanks

I guess it's a bite late but if it can help:
Make sure your session.autostart is turned off (0) in your php.ini
The way to use the session in Symfony 2 from the controler is the following:
$session = $this->getRequest()->getSession();
// store an attribute for reuse during a later user request
$session->set('foo', 'bar');
// in another controller for another request
$foo = $session->get('foo');
// use a default value if the key doesn't exist
$filters = $session->get('filters', array());
http://symfony.com/doc/current/book/controller.html#managing-the-session
Or from the view:
{{ app.session.get('foo') }}
You should also call start() even if it is automatically called when you read/write session data (because it is recommended and getId() doesn't call it for example)
$session->start();
$id = $session->getId();
http://symfony.com/doc/master/components/http_foundation/sessions.html
The reason you may not get the error on the production server is because it's priority is 'Notice' only.

Related

Session return null anyway

My project is using three different services and now I never can get sessions values, I've tried the laravel site tutorial and fallowing link question :
Laravel - Session returns null
But none of them worked!
In the first, i used this library:
use Session;
In a controller class :
$result = SocketHelper::sendRequest($req);
Session::put('uuid', $result->uuid);
Session::save();
Session::put('userId', $result->userID);
return Redirect::route('login_step_two');
In an other method :
$uuid = Session::get('uuid');
$userId = Session::get('userId');
But these are null! does I have to use cookie?
I recently upgrade to laravel 5.4
Please help me! It's made me confused!
Thanks.
Try saving Session explicitly like this, give it a try it worked for me, hope same for you.
Session::put('test_session', 'test message');
Session::save();
And retrieve it like this
echo Session::get('test_session');
And forget it like this:
Session::forget('test_session');
Session::save();
I understood the null result was becouse I was posting the value of $request to an other template and it was changed it the way :))) !
so easy to know !
Have you properly upgraded to laravel 5.4?
Laravel Docs
Sessions
Symfony Compatibility
Laravel's session handlers no longer implements Symfony's SessionInterface. Implementing this interface required us to implement extraneous features that were not needed by the framework. Instead, a new Illuminate\Contracts\Session\Session interface has been defined and may be used instead. The following code changes should also be applied:
All calls to the ->set() method should be changed to ->put(). Typically, Laravel applications would never call the set method since it has never been documented within the Laravel documentation. However, it is included here out of caution.
All calls to the ->getToken() method should be changed to ->token().
All calls to the $request->setSession() method should be changed to setLaravelSession().
Do you still have the rights to write session files in php session directory ?
Check the path returned by session_save_path() and check if your php user has the rights to write in it, check also if there is files in the directory and what are their creation date.

Laravel shared cookie detection issue in domain and subdomain

I am working on Laravel 5.4.30.
Imagine that we have a domain example.com and a subdomain of dev.example.com. The main domain is for master branch and the dev subdomain is for develop branch. We have cookie notice system that will be hidden after clicking on Hide Cookie Notice button. This works by setting a cookie forever.
We have set the SESSION_DOMAIN configs to each domain for each environment.
For main domain:
SESSION_DOMAIN=example.com
For dev subdomain:
SESSION_DOMAIN=dev.example.com
Now the issue comes from here. If we go to the example.com and click on hiding the cookie notice, a cookie will be set forever for main domain. After that we go to the dev.example.com and do the same. So a cookie will be set for subdomain as well. But this cookie has been set after previous one. (The order is important)
Now if we refresh the subdomain, we will see that notice again! (not hidden) The browser has read the main cookie because of .example.com set in domain parameter of cookie in the browser, so every subdomain will be affected. But the view still shows the notice because it cannot read any cookie for hiding.
Anyway I don't want to share that cookie across all subdomains. How can I achieve that? I think I should add a prefix for cookie name. But I don't know how to do it, that laravel automatically adds prefix to cookie name.
Any solutions?
You need to implement your own "retrieving" and "setting" a cookie.
Retrieving (has, get) cookies
Create yourself new class (anywhere you like, but I would do app/Foundation/Facades/) with name Cookie.
use \Illuminate\Support\Facades\Cookie as CookieStock;
class Cookie extends CookieStock {
//implement your own has(...);
public static function has($key)
{
return ! is_null(static::$app['request']->cookie(PREFIX . $key, null)); //get the prefix from .env file for your case APP_ENV
}
//implement your own get(...);
public static function get($key = null, $default = null) {...}
}
Now open up config/app.php and change corresponding alias (cookie).
Setting (make) cookies
Create yourself new provider (use artisan), and copy-paste code from Illuminate\Cookie\CookieServiceProvider.php and change namespaces.
Again open up config/app.php and change corresponding service provider with the new one.
Create yourself new class (anywhere you like, but I would do app/Foundation/Cookie/) with name CookieJar.
use \Illuminate\Cookie\CookieJar as CookieJarStock;
class CookieJar extends CookieJarStock {
//Override any method you think is relevant (my guess is make(), I am not sure at the moment about queue related methods)
public function make($name, $value, $minutes = 0, $path = null, $domain = null, $secure = false, $httpOnly = true)
{
// check before applying the PREFIX
if (!empty($name)) {
$name = PREFIX . $name; // get the PREFIX same way as before
}
return parent::make($name, $value, $minutes, $path, $domain, $secure, $httpOnly);
}
}
Update the code in your own cookie service provider to use your implementation of CookieJar (line 19).
Run $ composer dump-autoload, and you should be done.
Update
Since BorisD.Teoharov brought up, that if framework changes signature of CookieJarStocks make() (or any other cookie related function) in between the major versions, I made a example repository, that includes a test that can be used as is and it will fail if signature change happens.
It is as simple as this:
public function test_custom_cookie_jar_can_be_resolved()
{
resolve(\App\Foundation\Cookie\CookieJar::class);
$this->assertTrue(true);
}
Detailed how to can be inspected in the corresponding commit diff.
I've setup test environments to make sure, I'm not missing any details.
As in my former answer, I thought invalidating cookies will be sufficient for that case, but as #BorisD suggested it is not, and I've confirmed that on my tests.
So there are a few important notes, coming from my experiences...
Don't mix Laravel versions in subdomains - If using SESSION_DOMAIN you need to make sure your Laravel version matches (between root and subdomains), cause I've experimented with 5.4 under example.com domain and 5.6 under dev.example.com. This showed me some inconsistency in dealing with Cookies, so some important changes have been done, between these versions, and you can be sure it will not work correctly if you mix versions. I finally ended up with Laravel 5.6 on both domains, so I'm not 100% sure if that works on Laravel 5.4, but I think it should.
Make sure all your subdomains use the same APP_KEY - otherwise, Laravel will be unable to decrypt the Cookie, returning null value, cause all encryption/decryption in Laravel uses this app key...
SESSION_DOMAIN. In SESSION_DOMAIN I've pointed the same root domain like example.com for both domains. With this setting, I can create a cookie on root domain, and retrieve it correctly on both domains. After that setting, creating a cookie on subdomain forces root domain to receive new value from subdomains cookie also, and they are overridden. So I guess everything works here as requested in the original question.
Cookie make parameters - In case you want to use a subdomain in SESSION_DOMAIN, you can safely do that also. However, you need to make sure, important let's call them global cookies are defined in a bit different way. Cookie make syntax:
Cookie make(string $name, string $value, int $minutes, string $path = null, string $domain = null, bool $secure = false, bool $httpOnly = true)
So what's important here, you need to put your root domain for this particular cookie on creation like this for example:
return response($content)->cookie('name','value',10,null,'example.com')
Conclusions:
With this config, you should be able to access your Cookies properly under subdomains and your root domain.
You may probably need to update your Laravel installations to 5.6, which will force you to upgrade to PHP 7.1 at least (there were some changes to cookies in php also)
And finally, in your code, don't rely on Cookie existence, but on its values only (I don't know if that's in your case).
You could set a prefix for the cookie name depending on the environment.
First, add COOKIE_PREFIX to your env file.
COOKIE_PREFIX=dev
Then, use it when setting your cookie
$cookie = cookie(env('COOKIE_PREFIX', 'prod') . '_name', 'value', $minutes);
Then, retrieve it like so
$value = $request->cookie(env('COOKIE_PREFIX', 'prod') . '_name');
One of reason for that is for both app
APP_KEY and APP_NAME
should same in .env file,
that worked for me after 2 days of tries, I checked each library internally to get this solution.

Missed session variables when redirecting page

I have a problem regarding sessions in Laravel. I try to redirect the page and at the same time sending some session variables using the with() method:
return Redirect::To('/')->with('foo','bar');
But when the page comes up, the only session variables set are _token and locale, 'foo' and 'bar' do not appear. Running {!! var_dump(Session::all()); !!} gives:
array(2) { ["_token"]=> string(40) "l5NawtJdHJtanTErsya440UvPQIgqNExiryJIkIO" ["locale"]=> string(2) "se" }
The session stored in storage/framework/sessions strangely has other variables set, such as url and PHPDEBUGBAR_STACK_DATA that don't show up when redirecting.
Now, here's the real twist: It works perfectly when run on a different computer.
We tested with the same repository, same code, a fresh installation of laravel, same web browser, same OS (Mac) and same program for running the server locally (MAMP). On another computer it works fine, and on a third computer, but not on mine.
The application is in debug mode and I have tried clearing all caches in Laravel and in the browser nothing changed.
Does anyone have a clue on how this can be resolved?
with() method use to pass data to a view. If you want to add something to session use session()->flash->('foo', 'bar');(automatically erase after next request) or session()->put('foo', 'bar');
Apparently in config/session.php the variable domain was set to the production domain. So when using localhost on my computer, the cookie laravel_session couldn't be read or written.
It worked by using:
'domain' => null,

Yii2 $session->setId() not working

I'm using Ajax to log in a user from subdomain. The Yii2 app is on another subdomain. Both subdomains are configured to use same cookie and session domains and save paths. I'm including session ID with Ajax call to write the user information to the same session used by non-app subdomain like this:
$session = Yii::$app->session;
$session->open();
$session->setId($post["session"]);
$session["user.id"] = $user->id;
echo $session->id; // This does not return the same ID originating from post!
Unfortunately the user information IS NOT written to the session already existing, but a new one. Is there a session involved somewhere in the middle of login process or why isn't it working? I've also tried session_id($post["session"]), but nothing.
This was actually working on previous domain, so I must be missing something. All of the AJAX posted info is correct and checked, the user is logged in properly (checked the logs) but into wrong session.
Thanks in advance!
yii\web\Session::setId() is a wrapper for session_id(), you should read PHP documentation about this function :
string session_id([ string $id ])
If id is specified, it will replace the current session id. session_id() needs to be called before session_start() for that purpose.
So you should simply try :
$session = Yii::$app->session;
$session->setId($customId);
$session->open();
I Don't think you are following the correct way to SET & GET session.
Try This:
$session = Yii::$app->session;
$session->open();
$session->set('id', $post["session"]);
echo $session->get('id');
For more info, please click Session Management - Yii2

Sentry on Laravel 4 with MAMP

I'm using Laravel on MAMP PRO (PHP 5.4). Both are vanilla install and I got Laravel working okay.
Next, Installed Sentry.
Inside of a login function on controller:
$user = Sentry::authenticate($credentials, false); // this works. I can see the $user
But then upon an immediate redirect I use a filter:
Route::filter('auth.admin', function()
{
var_dump(Sentry::check()); // ** this gives me a bool(false);
die();
if ( ! Sentry::check())
{
return Redirect::route('admin.login');
}
});
So, I'm assuming that maybe there is a cookie that is not being set?
Solved...
For anyone else with this issue, this is a summary of the most common solutions on the Internet as well as how I solved my issue. I'm on MAMP/OSX, but this apparently made zero difference as I literally put up a vagrant/virtualbox and still had the same issue.
** Set 'domain' => 'yourdomain.com' in your config/session.php. EVEN IF YOU ARE ON A SUB DOMAIN like a.b.c.yourdomain.com, use ONLY the root domain (yourdomain.com) in your 'domain' variable as I just wrote it. ** This was my issue.
Make sure your session storage folder has write permissions.
Make sure you have a >0 lifetime in your session.php
Make sure you don't have whitespaces after any closing PHP which could cause the application not to shut down properly.
Try Switching between database sessions and file sessions.
As a last resort, try upgrade to 4.2, if possible. 4.1 had a known issue (as referenced in google).
Your issue is may no be with Laravel OR Sentry. It's probably a file or configuration issue as illustrated above. I pulled my hair out tracking this from Sentry to Laravel to Cookies to Session to Blah... Only to realize that it was finally a cookie issue which was caused by me not setting my ROOT domain (I was using the full

Resources