gebeer

Connect to PW without starting a session

Recommended Posts

Hello all,

I am using part of a PW install as a backend for a RESTful API.

Everytime a client consumes the API, a session is started. The RESTful approach is sessionless per definition and I would like to avoid sessions, if possible, for performance reasons.

When I look at the open sessions while only one client is getting or putting data through my REST API, I can see that there are quite a few (over 50) sessions open from that client.

The project is at a testing stage right now and I'm afraid that once 50 or 100 clients are connected, the sessions will put a big load on the server.

Is it advisable at all to try and avoid sessions?

How would I go about killing sessions or, even better, connect to my API endpoints without starting a session in the first place? 

  • Like 1

Share this post


Link to post
Share on other sites

The session is started by the wire/core/session.php, which currently seems to be a mandatory part of the core. Things like determining the current user and further down the road the template access management rely on a session being present. 

Share this post


Link to post
Share on other sites

Thanks for the answer.

I see that there is a config setting "$config->sessionExpireSeconds" which defaults to 86400 seconds.

Would it make any difference to the server load to reduce the session time?

Or does nayone have an idea how to deal with the situation?

Share this post


Link to post
Share on other sites

I'm not sure about the performance considerations of short vs long sessions, but I think it would be nice if the core would allow sessionless usage at least for unauthenticated requests. Shouldn't be to hard to declare everyone "guest", but there may be considerations regarding the $session api variable.

Share this post


Link to post
Share on other sites

Yeah, would be great if we could decide on a template basis whether to use sessions or not.

Share this post


Link to post
Share on other sites

maybe you could delete sessions using a cron.

every x minutes delete sessions longer than y seconds.

Share this post


Link to post
Share on other sites

Maybe you can use Module: Session Handler Database,

Don't know if it is a much better performance, but could be, as it don't need to touch filesystem.

You find it under modules -> core -> "Session". There you can activate it.

In this regard, it may also be useful to use this both settings for PHP in the site/config.php

@ini_set("session.gc_probability", 1);
@ini_set("session.gc_divisor", 100);

It has to do with the session garbage collector. Maybe you can tweak those settings. But I don't know, you have to research on your own for that. :)

Share this post


Link to post
Share on other sites

Thank you all for your suggestions.

@horst

I'm already storing sessions in the DB. Will have a look into the ini settings.

Meanwhile I found and interesting article which talks about using "session_write_close();". I will do some more research and post my findings here.

  • Like 3

Share this post


Link to post
Share on other sites

Just wanted to report my findings.

session_name($config->sessionName);
session_write_close();

does not have the desired effect. Sessions remain open.

session_name($config->sessionName);
session_write_close();
session_destroy();

throws a Warning: "Warning: session_destroy(): Trying to destroy uninitialized session"

What I think happens, is that "session_name($config->sessionName);" does not capture the original PW session.

If I do

$_SESSION = array();
session_destroy();

the Sessions get destroyed and are not recorded in the DB anymore.

I s there a way how I can get the PW session other than with $_SESSION?

EDIT: looking at var_dump($session), it is all protected properties.

  • Like 1

Share this post


Link to post
Share on other sites

I haven't tried this - but, it may be possible to solve this by creating two new session handler modules. A 'dummy' session handler for use with your API, and a clone of the Database handler for normal web requests.

Your initialisation code for each would detect if it's being loaded via the REST interface or traditional HTTP, and only register the hook into session when appropriate for it to do so.

In your dummy handler, all the storage methods would use an internal array/WireData object, and the other one would work exactly like the existing database one.

Share this post


Link to post
Share on other sites

There's no way to hook anything in regards to the session starting. This all happens in processwire's bootstrap part, before even the earliest hooks would run. But with Ryan having a processwire javascript api on the roadmap it may be time to discuss if pw 3.0 shouldn't support authentication without session.

  • Like 2

Share this post


Link to post
Share on other sites

Thank you all for your input.

@LostKobrakai

Would be great if this could be implemented into 3.0 :)

Share this post


Link to post
Share on other sites

This is what I was thinking of:
 

<?php

// Code for SessionHandler abstract class for reference
abstract class WireSessionHandler extends WireData implements Module {

	/**
	 * Initialize the save handler
	 *
	 */
	public function __construct() {
		$this->addHookBefore('Session::init', $this, 'attach'); 
		register_shutdown_function('session_write_close'); 
	}
}

class SessionHandlerDB extends WireSessionHandler implements Module, ConfigurableModule {

	public function __construct() {
		if ( ! isRestApi()) {
			parent::__construct();
		}
	}
}


class SessionHandlerDummy extends WireSessionHandler implements Module, ConfigurableModule {

	public function __construct() {
		if (isRestApi()) {
			parent::__construct();
		}
	}
}

If that doesn't work, there's an attach() function which could be overwritten/extended instead.

Share this post


Link to post
Share on other sites
5 hours ago, tiefenbacher_bluetomato said:

anything news about sessionles requests?

I don't think anything has changed since.

Share this post


Link to post
Share on other sites

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Peter Knight
      I have a demo site which I moved to a new VPS for client testing
      We noticed that leaving a page open and then revisiting the site can result in a 25 second(ish) to load time and will then throw a 500 Error.
      The hosting guys had a look and confirmed that the server is fine but the issue could be related to authentication or sessions.
      We are running Page Protector and ProCache so I wondered if there were any known bugs here and any recommended actions.
      My actual PW log doesn't show anything but the server log has plenty of these
       
      2018-12-06 08:14:00 Error xxx.141.1x.101 500 POST /who-we-are/ HTTP/1.0     1.58 K Apache access 2018-12-06 08:14:45 Warning xxx.141.1x.131   mod_fcgid: read data timeout in 45 seconds, referer: http://demo.abc.not/who-we-are/       Apache error 2018-12-06 08:14:45 Error xxx.141.1x.131   End of script output before headers: index.php, referer: http://demo.abc.not/who-we-are/       Apache error 2018-12-06 09:03:18 Error xxx.141.1x.131   2614#0: *667 recv() failed (104: Connection reset by peer) while reading response header from upstream       nginx error Thanks
      P
    • By alejandro
      Hello, after creating an array and assigning it to a variable in session:
      $order = array (); $order['token'] = 'token'; $order['product'] = 'product-name'; $session->order = $order; I try to insert another item:
      $session->order['price'] = 'price'; But it doesn't work: 
      Notice: Indirect modification of overloaded property ProcessWire\Session::$order has no effect in... Isn't possible to modify such session variable? I could build another array from the session variable, add the new item, and then store it again in session, but doesn't looks good.
      Thanks!
    • By dragan
      If I have two PW sites that sit in separate folders, I can't be logged-in in both sites.
      e.g.
      site.com/project-a/pw-admin-slug/
      site.com/project-b/pw-admin-slug/
      If I login to project-a, then also login to project-b, get back to the first site, I have to login again.
      Is the cookie / session mechanism storing my domain? If it does, and it's meant to be some sort of security enhancement, it should not check my domain, but root-URL of the PW-installation. (strangely, this doesn't happen on localhost)
      Is it possible to prevent that behavior? Often I have two sites open (e.g. check to see if I have the same CKEditor setup and quickly copy and paste it, or copy a user-role)
    • By Jarden Black
      Hi everyone,
      [edit: do not loose your time reading this post, I solved it by disabling cache in the Pages2Pdf module... sorry 😓]
       
      I do not know if I should post on the Pages2Pdf thread or here. Mods, feel free to move the post.
       
      Since three days I am scratching my head  to understand a weird thing happening with $session and $config->debug used in conjunction with Pages2Pdf module. For information, I tested it on a fresh install of ProcessWire 3.0.96 with PHP-7.0.28 and Pages2Pdf-1.1.7 (domain: http://session.sites.sek/). I will try to explain what is going on.
       
      What I am trying to achieve :
      In a template, I need to set some sessions variables which are then echo'd in the PDF document.
      (on the test installation, the basic-page template (page /about/?pages2pdf) serve the PDF, the home and sitemap template set the session variable.)
       
      The problem :
      From the template sitemap, I set a variable: $session->setFor('pdf', 'myvar', 'Session set from Sitemap template');
      From the template home, I set a variable: $session->setFor('pdf', 'myvar', 'Session set from Home template');
      Then in the PDF default template, I echo the session variable: <p>Session: <?= $session->getFor('pdf', 'myvar'); ?></p>
       
      Now I turn ON debug mode ($config->debug = true) :
      Then I navigate to  "http://session.sites.sek/home/" and the session variable "myvar" is set to "Session set from Home template". Then I navigate to  "http://session.sites.sek/sitemap/" and the session variable "myvar" is set to "Session set from Sitemap template". Now I want my PDF document, so I navigate to "http://session.sites.sek/about/?pages2pdf=1" and I get my PDF document with the right session var : "Session set from Sitemap template" For the moment, nothing special happen. Everything work great. We are in debug mode.
       
      Now I turn OFF debug mode ($config->debug = false) :
      Then I navigate to  "http://session.sites.sek/home/" and the session variable "myvar" is set to "Session set from Home template". Then I navigate to  "http://session.sites.sek/sitemap/" and the session variable "myvar" is set to "Session set from Sitemap template". Then I navigate back to "http://session.sites.sek/home/" and the session variable "myvar" is set back to "Session set from Home template". Now I want my PDF document - as expected, the "myvar" should be set to "Session set from Home template" - so I navigate to "http://session.sites.sek/about/?pages2pdf=1" and here the problem happen. Instead of echoing  "Session set from Home template" in the PDF document, the phrase "Session set from sitemap" is echo'd (the last value recorded before switching from debug ON).  
       
      I made two small screencasts to show the issue :
      DEBUG ON (Everything is OK)
       
      DEBUG OFF
       
       
      I am missing something ? EDIT: YES, you are dumb!
       
       
    • By flydev
      Hi everyone,
      [edit: do not loose your time reading this post, I solved it by disabling cache in the Pages2Pdf module... sorry 😓]
       
      I do not know if I should post on the Pages2Pdf thread or here. Mods, feel free to move the post.
       
      Since three days I am scratching my head to understand a weird thing happening with $session and $config->debug used in conjunction with Pages2Pdf module. For information, I tested it on a fresh install of ProcessWire 3.0.96 with PHP-7.0.28 and Pages2Pdf-1.1.7 (domain: http://session.sites.sek/). I will try to explain what is going on.
       
      What I am trying to achieve :
      In a template, I need to set some sessions variables which are then echo'd in the PDF document.
      (on the test installation, the basic-page template (page /about/?pages2pdf) serve the PDF, the home and sitemap template set the session variable.)
       
      The problem :
      From the template sitemap, I set a variable: $session->setFor('pdf', 'myvar', 'Session set from Sitemap template');
      From the template home, I set a variable: $session->setFor('pdf', 'myvar', 'Session set from Home template');
      Then in the PDF default template, I echo the session variable: <p>Session: <?= $session->getFor('pdf', 'myvar'); ?></p>
       
      Now I turn ON debug mode ($config->debug = true) :
      Then I navigate to  "http://session.sites.sek/home/" and the session variable "myvar" is set to "Session set from Home template". Then I navigate to  "http://session.sites.sek/sitemap/" and the session variable "myvar" is set to "Session set from Sitemap template". Now I want my PDF document, so I navigate to "http://session.sites.sek/about/?pages2pdf=1" and I get my PDF document with the right session var : "Session set from Sitemap template" For the moment, nothing special happen. Everything work great. We are in debug mode.
       
      Now I turn OFF debug mode ($config->debug = false) :
      Then I navigate to  "http://session.sites.sek/home/" and the session variable "myvar" is set to "Session set from Home template". Then I navigate to  "http://session.sites.sek/sitemap/" and the session variable "myvar" is set to "Session set from Sitemap template". Then I navigate back to "http://session.sites.sek/home/" and the session variable "myvar" is set back to "Session set from Home template". Now I want my PDF document - as expected, the "myvar" should be set to "Session set from Home template" - so I navigate to "http://session.sites.sek/about/?pages2pdf=1" and here the problem happen. Instead of echoing  "Session set from Home template" in the PDF document, the phrase "Session set from sitemap" is echo'd (the last value recorded before switching from debug ON).  
       
      I made two small screencasts to show the issue :
      DEBUG ON (Everything is OK)
       
      DEBUG OFF
       
       
      I am missing something ? EDIT: YES, you are dumb!
      Why it is working with debug mode ON and not vice-versa ?
      Is there someone who already spotted this strange behavior ?
      Is there a PHP settings which should be modified ?
       
      ====================================================
      Edit:
      I needed to post just to figure myself that Pages2Pdf cache the document when $config->debug is false.
      😬😬😬